chore: remove local replace directives and update dependencies

- Update github.com/luxfi/keys v1.0.5 → v1.0.6
- Update github.com/luxfi/genesis v1.5.18 → v1.5.19
- Remove local replace directives for keys and genesis
- Use published package versions for reproducible builds
This commit is contained in:
Zach Kelling
2026-01-03 07:05:17 -08:00
parent 5d4bdf3368
commit 4e2a4e432e
59 changed files with 909 additions and 916 deletions
+38 -101
View File
@@ -1,113 +1,50 @@
# https://golangci-lint.run/usage/configuration/
# golangci-lint v2 configuration
version: "2"
run:
timeout: 10m
# skip auto-generated files.
skip-files:
- ".*\\.pb\\.go$"
- ".*mock.*"
issues:
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
formatters:
enable:
- gofmt
- goimports
linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
disable-all: true
default: none
enable:
- asciicheck
- depguard
- errcheck
- errorlint
- exportloopref
- goconst
- gocritic
- gofmt
- gofumpt
- goimports
- revive
- gosec
- gosimple
- govet
- ineffassign
- misspell
- nakedret
- nolintlint
- prealloc
- stylecheck
- unconvert
- unparam
- unused
- unconvert
- whitespace
- staticcheck
# - bodyclose
# - structcheck
# - lll
# - gomnd
# - goprintffuncname
# - interfacer
# - typecheck
# - goerr113
# - noctx
- misspell
linters-settings:
errorlint:
# Check for plain type assertions and type switches.
asserts: false
# Check for plain error comparisons.
comparison: false
revive:
settings:
staticcheck:
checks:
- "all"
- "-SA6002"
- "-SA1019"
- "-ST1000"
- "-ST1021"
- "-QF1008"
exclusions:
generated: lax
presets:
- comments
rules:
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr
- name: bool-literal-in-expr
disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return
- name: early-return
disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines
- name: empty-lines
disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#struct-tag
- name: struct-tag
disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-naming
- name: unexported-naming
disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error
- name: unhandled-error
disabled: false
arguments:
- "fmt.Fprint"
- "fmt.Fprintf"
- "fmt.Print"
- "fmt.Printf"
- "fmt.Println"
- "rand.Read"
- "sb.WriteString"
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter
- name: unused-parameter
disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-receiver
- name: unused-receiver
disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break
- name: useless-break
disabled: false
staticcheck:
go: "1.19"
# https://staticcheck.io/docs/options#checks
checks:
- "all"
- "-SA6002" # argument should be pointer-like to avoid allocation, for sync.Pool
- "-SA1019" # deprecated packages e.g., golang.org/x/crypto/ripemd160
# https://golangci-lint.run/usage/linters#gosec
gosec:
excludes:
- G107 # https://securego.io/docs/rules/g107.html
depguard:
list-type: blacklist
packages-with-error-message:
- io/ioutil: 'io/ioutil is deprecated. Use package io or os instead.'
- github.com/stretchr/testify/assert: 'github.com/stretchr/testify/require should be used instead.'
include-go-root: true
- path: ".*\\.pb\\.go$"
linters:
- all
- path: ".*mock.*"
linters:
- all
- path: _test\.go
linters:
- errcheck
- linters:
- errcheck
text: "Error return value of .*(Close|Flush|Fprintln|Fprintf|Print|Printf|Println|Write|Signal|Kill|RemoveAll|Sync|Sscanf|MarkFlagRequired).*is not checked"
issues:
max-same-issues: 0
+1 -1
View File
@@ -68,7 +68,7 @@ type Client interface {
PChainAPI() *platformvm.Client
XChainAPI() *exchangevm.Client
XChainWalletAPI() *exchangevm.WalletClient
CChainAPI() interface{} // evmclient.Client
CChainAPI() interface{} // evmclient.Client
CChainEthAPI() EthClient // ethclient websocket wrapper that adds mutexed calls, and lazy conn init (on first call)
InfoAPI() *info.Client
HealthAPI() HealthClient
-1
View File
@@ -87,7 +87,6 @@ func (_m *EthClient) AcceptedNonceAt(_a0 context.Context, _a1 common.Address) (u
return r0, r1
}
// BalanceAt provides a mock function with given fields: _a0, _a1, _a2
func (_m *EthClient) BalanceAt(_a0 context.Context, _a1 common.Address, _a2 *big.Int) (*big.Int, error) {
ret := _m.Called(_a0, _a1, _a2)
+21 -21
View File
@@ -12,9 +12,9 @@ import (
"sync"
"time"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/rpcpb"
"github.com/luxfi/log"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
@@ -59,7 +59,7 @@ type Client interface {
}
type client struct {
cfg Config
cfg Config
logger log.Logger
conn *grpc.ClientConn
@@ -88,7 +88,7 @@ func New(cfg Config, logger log.Logger) (Client, error) {
return &client{
cfg: cfg,
logger: logger,
logger: logger,
conn: conn,
pingc: rpcpb.NewPingServiceClient(conn),
controlc: rpcpb.NewControlServiceClient(conn),
@@ -114,11 +114,11 @@ func (c *client) Start(ctx context.Context, execPath string, opts ...OpOption) (
ret.applyOpts(opts)
req := &rpcpb.StartRequest{
ExecPath: execPath,
NumNodes: &ret.numNodes,
ChainConfigs: ret.chainConfigs,
UpgradeConfigs: ret.upgradeConfigs,
ChainConfigFiles: ret.chainConfigs,
ExecPath: execPath,
NumNodes: &ret.numNodes,
ChainConfigs: ret.chainConfigs,
UpgradeConfigs: ret.upgradeConfigs,
ChainConfigFiles: ret.chainConfigs,
}
if ret.trackChains != "" {
req.WhitelistedChains = &ret.trackChains
@@ -271,12 +271,12 @@ func (c *client) AddNode(ctx context.Context, name string, execPath string, opts
ret.applyOpts(opts)
req := &rpcpb.AddNodeRequest{
Name: name,
ExecPath: execPath,
NodeConfig: &ret.globalNodeConfig,
ChainConfigs: ret.chainConfigs,
UpgradeConfigs: ret.upgradeConfigs,
ChainConfigFiles: ret.chainConfigs,
Name: name,
ExecPath: execPath,
NodeConfig: &ret.globalNodeConfig,
ChainConfigs: ret.chainConfigs,
UpgradeConfigs: ret.upgradeConfigs,
ChainConfigFiles: ret.chainConfigs,
}
if ret.pluginDir != "" {
@@ -354,10 +354,10 @@ func (c *client) LoadSnapshot(ctx context.Context, snapshotName string, opts ...
ret := &Op{}
ret.applyOpts(opts)
req := rpcpb.LoadSnapshotRequest{
SnapshotName: snapshotName,
ChainConfigs: ret.chainConfigs,
UpgradeConfigs: ret.upgradeConfigs,
ChainConfigFiles: ret.chainConfigs,
SnapshotName: snapshotName,
ChainConfigs: ret.chainConfigs,
UpgradeConfigs: ret.upgradeConfigs,
ChainConfigFiles: ret.chainConfigs,
}
if ret.execPath != "" {
req.ExecPath = &ret.execPath
@@ -399,13 +399,13 @@ func (c *client) Close() error {
type Op struct {
numNodes uint32
execPath string
trackChains string
trackChains string
globalNodeConfig string
rootDataDir string
pluginDir string
chainSpecs []*rpcpb.BlockchainSpec
chainSpecs []*rpcpb.BlockchainSpec
customNodeConfigs map[string]string
numChains uint32
numChains uint32
chainConfigs map[string]string
upgradeConfigs map[string]string
pChainConfigs map[string]string
+6 -6
View File
@@ -14,14 +14,14 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/luxfi/netrunner/client"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/rpcpb"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/netrunner/ux"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/spf13/cobra"
)
@@ -34,11 +34,11 @@ const clientRootDirPrefix = "client"
var (
logLevel string
logDir string
trackChains string
trackChains string
endpoint string
dialTimeout time.Duration
requestTimeout time.Duration
logger log.Logger
logger log.Logger
)
// NOTE: Naming convention for node names is currently `node` + number, i.e. `node1,node2,node3,...node101`
@@ -86,12 +86,12 @@ func NewCommand() *cobra.Command {
}
var (
luxdBinPath string
luxdBinPath string
numNodes uint32
pluginDir string
globalNodeConfig string
addNodeConfig string
chainSpecsStr string
chainSpecsStr string
customNodeConfigs string
rootDataDir string
chainConfigs string
+7 -1
View File
@@ -117,6 +117,12 @@ func main() {
"proofOfPossession": "%s"
}
}%s
`, vk.NodeID.String(), vk.BLSPublicKeyHex(), vk.BLSPoPHex(), func() string { if i < 4 { return "," } else { return "" } }())
`, vk.NodeID.String(), vk.BLSPublicKeyHex(), vk.BLSPoPHex(), func() string {
if i < 4 {
return ","
} else {
return ""
}
}())
}
}
+2 -1
View File
@@ -4,9 +4,10 @@
package commands
import (
"github.com/luxfi/log"
"fmt"
"github.com/luxfi/log"
"github.com/spf13/cobra"
)
+2 -2
View File
@@ -4,7 +4,6 @@
package commands
import (
"github.com/luxfi/log"
"context"
"fmt"
"os"
@@ -12,8 +11,9 @@ import (
"text/tabwriter"
"time"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/engines"
_ "github.com/luxfi/netrunner/engines/lux"
_ "github.com/luxfi/netrunner/engines/geth"
_ "github.com/luxfi/netrunner/engines/lux"
"github.com/spf13/cobra"
+2 -1
View File
@@ -4,9 +4,10 @@
package commands
import (
"github.com/luxfi/log"
"fmt"
"github.com/luxfi/log"
"github.com/spf13/cobra"
)
+2 -1
View File
@@ -4,13 +4,14 @@
package commands
import (
"github.com/luxfi/log"
"fmt"
"os"
"path/filepath"
"text/tabwriter"
"time"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/orchestrator"
"github.com/spf13/cobra"
)
+2 -1
View File
@@ -4,11 +4,12 @@
package commands
import (
"github.com/luxfi/log"
"fmt"
"os"
"text/tabwriter"
"github.com/luxfi/log"
"github.com/spf13/cobra"
)
+2 -1
View File
@@ -4,11 +4,12 @@
package commands
import (
"github.com/luxfi/log"
"context"
"fmt"
"time"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/engines"
"github.com/spf13/cobra"
)
+2 -2
View File
@@ -7,11 +7,11 @@ import (
"context"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/luxfi/netrunner/client"
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/netrunner/ux"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/spf13/cobra"
)
+2 -2
View File
@@ -11,11 +11,11 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/luxfi/netrunner/server"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/spf13/cobra"
)
+16 -16
View File
@@ -25,14 +25,14 @@ func init() {
// LuxEngine wraps luxd node management
type LuxEngine struct {
name string
binary string
dataDir string
config *engines.NodeConfig
process *exec.Cmd
httpClient *http.Client
rpcEndpoint string
startTime time.Time
name string
binary string
dataDir string
config *engines.NodeConfig
process *exec.Cmd
httpClient *http.Client
rpcEndpoint string
startTime time.Time
// Cached info
networkID uint32
@@ -50,10 +50,10 @@ func NewLuxEngine(name string, binary string) (engines.Engine, error) {
}, nil
}
func (e *LuxEngine) Name() string { return e.name }
func (e *LuxEngine) Type() engines.EngineType { return engines.EngineLux }
func (e *LuxEngine) NetworkID() uint32 { return e.networkID }
func (e *LuxEngine) ChainID() ids.ID { return e.chainID }
func (e *LuxEngine) Name() string { return e.name }
func (e *LuxEngine) Type() engines.EngineType { return engines.EngineLux }
func (e *LuxEngine) NetworkID() uint32 { return e.networkID }
func (e *LuxEngine) ChainID() ids.ID { return e.chainID }
func (e *LuxEngine) ParentChain() *engines.ChainInfo { return nil } // L1
func (e *LuxEngine) Start(ctx context.Context, config *engines.NodeConfig) error {
@@ -188,9 +188,9 @@ func (e *LuxEngine) Health(ctx context.Context) (*engines.HealthStatus, error) {
version, _ := e.getNodeVersion(ctx)
return &engines.HealthStatus{
Healthy: healthy,
PeerCount: peerCount,
Version: version,
Healthy: healthy,
PeerCount: peerCount,
Version: version,
// BlockHeight from C-Chain would require eth client
}, nil
}
@@ -359,7 +359,7 @@ func (e *LuxEngine) getPeerCount(ctx context.Context) (int, error) {
}
var resp struct {
NumPeers int `json:"numPeers"`
NumPeers int `json:"numPeers"`
Peers []interface{} `json:"peers"`
}
if err := json.Unmarshal(result, &resp); err != nil {
+17 -15
View File
@@ -53,18 +53,20 @@ type mockEngine struct {
name string
}
func (m *mockEngine) Name() string { return m.name }
func (m *mockEngine) Type() EngineType { return "test" }
func (m *mockEngine) NetworkID() uint32 { return 1337 }
func (m *mockEngine) ChainID() ids.ID { return ids.Empty }
func (m *mockEngine) ParentChain() *ChainInfo { return nil }
func (m *mockEngine) Start(_ context.Context, _ *NodeConfig) error { return nil }
func (m *mockEngine) Stop(_ context.Context) error { return nil }
func (m *mockEngine) Restart(_ context.Context) error { return nil }
func (m *mockEngine) Health(_ context.Context) (*HealthStatus, error) { return &HealthStatus{Healthy: true}, nil }
func (m *mockEngine) IsRunning() bool { return true }
func (m *mockEngine) Uptime() time.Duration { return 0 }
func (m *mockEngine) RPCEndpoint() string { return "http://localhost:8545" }
func (m *mockEngine) WSEndpoint() string { return "ws://localhost:8546" }
func (m *mockEngine) P2PEndpoint() string { return "localhost:30303" }
func (m *mockEngine) Metrics() map[string]interface{} { return map[string]interface{}{} }
func (m *mockEngine) Name() string { return m.name }
func (m *mockEngine) Type() EngineType { return "test" }
func (m *mockEngine) NetworkID() uint32 { return 1337 }
func (m *mockEngine) ChainID() ids.ID { return ids.Empty }
func (m *mockEngine) ParentChain() *ChainInfo { return nil }
func (m *mockEngine) Start(_ context.Context, _ *NodeConfig) error { return nil }
func (m *mockEngine) Stop(_ context.Context) error { return nil }
func (m *mockEngine) Restart(_ context.Context) error { return nil }
func (m *mockEngine) Health(_ context.Context) (*HealthStatus, error) {
return &HealthStatus{Healthy: true}, nil
}
func (m *mockEngine) IsRunning() bool { return true }
func (m *mockEngine) Uptime() time.Duration { return 0 }
func (m *mockEngine) RPCEndpoint() string { return "http://localhost:8545" }
func (m *mockEngine) WSEndpoint() string { return "ws://localhost:8546" }
func (m *mockEngine) P2PEndpoint() string { return "localhost:30303" }
func (m *mockEngine) Metrics() map[string]interface{} { return map[string]interface{}{} }
+27 -27
View File
@@ -23,16 +23,16 @@ import (
// Eth2Engine implements Ethereum 2.0 consensus (Beacon Chain + Execution Layer)
type Eth2Engine struct {
mu sync.RWMutex
name string
beaconBinary string // Consensus client (e.g., Prysm, Lighthouse, Teku)
executionBinary string // Execution client (e.g., Geth, Erigon, Nethermind)
beaconCmd *exec.Cmd
executionCmd *exec.Cmd
config *NodeConfig
startTime time.Time
running bool
dataDir string
mu sync.RWMutex
name string
beaconBinary string // Consensus client (e.g., Prysm, Lighthouse, Teku)
executionBinary string // Execution client (e.g., Geth, Erigon, Nethermind)
beaconCmd *exec.Cmd
executionCmd *exec.Cmd
config *NodeConfig
startTime time.Time
running bool
dataDir string
// Eth2 specific
chainID uint64
@@ -66,27 +66,27 @@ const (
// Eth2Config contains Ethereum 2.0 specific configuration
type Eth2Config struct {
ChainID uint64 `json:"chain_id"`
NetworkName string `json:"network_name"`
ConsensusClient ConsensusClient `json:"consensus_client"`
ExecutionClient ExecutionClient `json:"execution_client"`
ValidatorEnabled bool `json:"validator_enabled"`
ValidatorKeys []string `json:"validator_keys,omitempty"`
InitialValidators []string `json:"initial_validators,omitempty"`
TerminalTotalDifficulty string `json:"terminal_total_difficulty"`
GenesisTime uint64 `json:"genesis_time"`
ChainID uint64 `json:"chain_id"`
NetworkName string `json:"network_name"`
ConsensusClient ConsensusClient `json:"consensus_client"`
ExecutionClient ExecutionClient `json:"execution_client"`
ValidatorEnabled bool `json:"validator_enabled"`
ValidatorKeys []string `json:"validator_keys,omitempty"`
InitialValidators []string `json:"initial_validators,omitempty"`
TerminalTotalDifficulty string `json:"terminal_total_difficulty"`
GenesisTime uint64 `json:"genesis_time"`
}
// BeaconNodeStatus represents beacon chain status
type BeaconNodeStatus struct {
HeadSlot uint64 `json:"head_slot"`
SyncDistance uint64 `json:"sync_distance"`
IsSyncing bool `json:"is_syncing"`
IsOptimistic bool `json:"is_optimistic"`
ElOffline bool `json:"el_offline"`
CurrentEpoch uint64 `json:"current_epoch"`
FinalizedEpoch uint64 `json:"finalized_epoch"`
JustifiedEpoch uint64 `json:"justified_epoch"`
HeadSlot uint64 `json:"head_slot"`
SyncDistance uint64 `json:"sync_distance"`
IsSyncing bool `json:"is_syncing"`
IsOptimistic bool `json:"is_optimistic"`
ElOffline bool `json:"el_offline"`
CurrentEpoch uint64 `json:"current_epoch"`
FinalizedEpoch uint64 `json:"finalized_epoch"`
JustifiedEpoch uint64 `json:"justified_epoch"`
}
// NewEth2Engine creates a new Ethereum 2.0 engine
+4 -4
View File
@@ -50,10 +50,10 @@ func NewGethEngine(name string, binary string) (engines.Engine, error) {
}, nil
}
func (e *GethEngine) Name() string { return e.name }
func (e *GethEngine) Type() engines.EngineType { return engines.EngineGeth }
func (e *GethEngine) NetworkID() uint32 { return e.networkID }
func (e *GethEngine) ChainID() ids.ID { return e.chainID }
func (e *GethEngine) Name() string { return e.name }
func (e *GethEngine) Type() engines.EngineType { return engines.EngineGeth }
func (e *GethEngine) NetworkID() uint32 { return e.networkID }
func (e *GethEngine) ChainID() ids.ID { return e.chainID }
func (e *GethEngine) ParentChain() *engines.ChainInfo { return nil } // L1
func (e *GethEngine) Start(ctx context.Context, config *engines.NodeConfig) error {
+7 -7
View File
@@ -53,10 +53,10 @@ func NewLuxEngine(name string, binary string) (engines.Engine, error) {
}, nil
}
func (e *LuxEngine) Name() string { return e.name }
func (e *LuxEngine) Type() engines.EngineType { return engines.EngineLux }
func (e *LuxEngine) NetworkID() uint32 { return e.networkID }
func (e *LuxEngine) ChainID() ids.ID { return e.chainID }
func (e *LuxEngine) Name() string { return e.name }
func (e *LuxEngine) Type() engines.EngineType { return engines.EngineLux }
func (e *LuxEngine) NetworkID() uint32 { return e.networkID }
func (e *LuxEngine) ChainID() ids.ID { return e.chainID }
func (e *LuxEngine) ParentChain() *engines.ChainInfo { return nil } // L1
func (e *LuxEngine) Start(ctx context.Context, config *engines.NodeConfig) error {
@@ -198,9 +198,9 @@ func (e *LuxEngine) Health(ctx context.Context) (*engines.HealthStatus, error) {
}
return &engines.HealthStatus{
Healthy: healthResp.Healthy,
PeerCount: len(peers),
Version: versions.Version,
Healthy: healthResp.Healthy,
PeerCount: len(peers),
Version: versions.Version,
// BlockHeight from C-Chain would require eth client
}, nil
}
+8 -8
View File
@@ -38,14 +38,14 @@ type OPStackEngine struct {
// RollupConfig contains OP Stack rollup configuration
type RollupConfig struct {
Genesis RollupGenesis `json:"genesis"`
BlockTime uint64 `json:"block_time"`
MaxSequencerDrift uint64 `json:"max_sequencer_drift"`
SeqWindowSize uint64 `json:"seq_window_size"`
ChannelTimeout uint64 `json:"channel_timeout"`
L1ChainID uint64 `json:"l1_chain_id"`
L2ChainID uint64 `json:"l2_chain_id"`
P2PSequencerAddress string `json:"p2p_sequencer_address"`
Genesis RollupGenesis `json:"genesis"`
BlockTime uint64 `json:"block_time"`
MaxSequencerDrift uint64 `json:"max_sequencer_drift"`
SeqWindowSize uint64 `json:"seq_window_size"`
ChannelTimeout uint64 `json:"channel_timeout"`
L1ChainID uint64 `json:"l1_chain_id"`
L2ChainID uint64 `json:"l2_chain_id"`
P2PSequencerAddress string `json:"p2p_sequencer_address"`
}
// RollupGenesis contains OP Stack genesis configuration
+4 -4
View File
@@ -15,10 +15,10 @@ import (
type EngineType string
const (
EngineLux EngineType = "lux"
EngineGeth EngineType = "geth"
EngineOP EngineType = "op"
EngineEth2 EngineType = "eth2"
EngineLux EngineType = "lux"
EngineGeth EngineType = "geth"
EngineOP EngineType = "op"
EngineEth2 EngineType = "eth2"
)
// ChainInfo describes a blockchain's network properties
+2 -2
View File
@@ -9,10 +9,10 @@ import (
"syscall"
"time"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
)
const (
+2 -2
View File
@@ -8,13 +8,13 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/node/config"
"github.com/luxfi/node/staking"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
)
const (
+5 -5
View File
@@ -12,11 +12,11 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/node/config"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
)
const (
@@ -209,9 +209,9 @@ func run(logger log.Logger) error {
createCtx, createCancel := context.WithTimeout(context.Background(), createBlockchainTimeout)
chainSpec := []network.ChainSpec{
{
VMName: chain.VMName,
Genesis: genesis,
Alias: chain.Alias,
VMName: chain.VMName,
Genesis: genesis,
Alias: chain.Alias,
BlockchainName: chain.Alias, // Use unique name for each chain
},
}
+2 -2
View File
@@ -15,11 +15,11 @@ require (
github.com/luxfi/consensus v1.22.47
github.com/luxfi/const v1.4.0
github.com/luxfi/crypto v1.17.32
github.com/luxfi/genesis v1.5.18
github.com/luxfi/genesis v1.5.19
github.com/luxfi/geth v1.16.67
github.com/luxfi/go-bip39 v1.1.2
github.com/luxfi/ids v1.2.6
github.com/luxfi/keys v1.0.5
github.com/luxfi/keys v1.0.6
github.com/luxfi/log v1.2.1
github.com/luxfi/math v1.2.0
github.com/luxfi/metric v1.4.8
+4 -4
View File
@@ -249,8 +249,8 @@ github.com/luxfi/crypto v1.17.32 h1:qEKDETNMeU7T82UMEEGYh0bbJ0ZZdx0sAMRwFXt69aQ=
github.com/luxfi/crypto v1.17.32/go.mod h1:laZTnEq0BD/fnPhd5ke/79WgFhV3TZjmfPxk+b8zbrE=
github.com/luxfi/database v1.2.18 h1:yppRuZf3FKnr3v4o+UHNfSW+cXtUIUibtyki0+EqiIs=
github.com/luxfi/database v1.2.18/go.mod h1:dYxaF30KGJQzuxA3VH7+WGU5/dhwRyzLgzSk9F3wje0=
github.com/luxfi/genesis v1.5.18 h1:DDNFDyYT+AtSX78XBV1nGeuvR4404XPAkXnnrlJSV78=
github.com/luxfi/genesis v1.5.18/go.mod h1:888i1w8e67HIpgLuveIdd+3ESWCXHgnz7cijF6dDAKI=
github.com/luxfi/genesis v1.5.19 h1:q9ETV3NXTlJBhhkVKYDidaQqBDb1jgY3TdaLPfBGu0k=
github.com/luxfi/genesis v1.5.19/go.mod h1:888i1w8e67HIpgLuveIdd+3ESWCXHgnz7cijF6dDAKI=
github.com/luxfi/geth v1.16.67 h1:ILPG59XNnNKIz1YNO1fJFV+doZXBjcQkb4oXQyz1HUM=
github.com/luxfi/geth v1.16.67/go.mod h1:QWPyY3vlGQfm8SX/PE6q4XHTBe7X4Gw+SGDJi5QU1pg=
github.com/luxfi/go-bip32 v1.0.2 h1:7vFbb+Wr4Z499q2tuCLdd7wWjtn8sH+HWBlx76mhH9Y=
@@ -261,8 +261,8 @@ github.com/luxfi/ids v1.2.6 h1:Ru86pltAcWPhCT7FH/MwwuAYXkeZbt9ZwfuR883c8MI=
github.com/luxfi/ids v1.2.6/go.mod h1:svLsj7e6ixJVfRYaQqv9RWjBIW11Vz738+d08BVpeCg=
github.com/luxfi/keychain v1.0.1 h1:8tTzPnZSi0M6UtKRBCypnGFrLNry9BvWfS5ol33yDF0=
github.com/luxfi/keychain v1.0.1/go.mod h1:X7HLk5QRZ1VHJxovAyBL6z7f/nlosoXlveEtvUGhoaw=
github.com/luxfi/keys v1.0.5 h1:ZzE2wHDxSiIcufkYlp7twmTKGB0mczjE67uM3uAP2Ag=
github.com/luxfi/keys v1.0.5/go.mod h1:hVqfOm6n4/ZN2O6AirlLEpgBhW8bsxNo2EbiNvggGUk=
github.com/luxfi/keys v1.0.6 h1:mKB0xjQoNpJxj59UNfdPfuqUoRT48Itt7PvRXU+X3iY=
github.com/luxfi/keys v1.0.6/go.mod h1:hVqfOm6n4/ZN2O6AirlLEpgBhW8bsxNo2EbiNvggGUk=
github.com/luxfi/log v1.2.1 h1:L2JM8MjGPF8rBnY+EXODS9x5OQTGSgeQ1SPFmeB+oPY=
github.com/luxfi/log v1.2.1/go.mod h1:0vJzb4Hl9fvgwWDMKcbCD/SYH3bO0iSmgZMcYdfdl1o=
github.com/luxfi/math v1.2.0 h1:cZVQQj1PrIWh3Oy6xfbBL44xay4QFuAXZBg9+pWPBmE=
+25 -24
View File
@@ -26,26 +26,27 @@ import (
"github.com/luxfi/node/vms/components/verify"
"github.com/luxfi/node/wallet/chain/x"
"maps"
"slices"
luxconfig "github.com/luxfi/config"
constants "github.com/luxfi/const"
"github.com/luxfi/crypto/bls"
"github.com/luxfi/crypto/secp256k1"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/math/set"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/utils"
luxconfig "github.com/luxfi/config"
"github.com/luxfi/node/api/admin"
"github.com/luxfi/node/config"
"github.com/luxfi/crypto/secp256k1"
"github.com/luxfi/ids"
"github.com/luxfi/const"
"github.com/luxfi/math/set"
"github.com/luxfi/crypto/bls"
"github.com/luxfi/log"
"github.com/luxfi/node/vms/platformvm"
"github.com/luxfi/node/vms/platformvm/signer"
"github.com/luxfi/node/vms/platformvm/txs"
"github.com/luxfi/node/vms/secp256k1fx"
pwallet "github.com/luxfi/node/wallet/chain/p"
pwalletwallet "github.com/luxfi/node/wallet/chain/p/wallet"
"maps"
"slices"
pbuilder "github.com/luxfi/node/wallet/chain/p/builder"
psigner "github.com/luxfi/node/wallet/chain/p/signer"
@@ -73,7 +74,7 @@ const (
// Most P-chain API calls should complete in <5s on localhost
defaultTimeout = 30 * time.Second
stakingMinimumLeadTime = 25 * time.Second
minStakeDuration = 24 * 14 * time.Hour
minStakeDuration = 24 * 14 * time.Hour
// FAIL FAST: Reduced from 45s to 30s for local deployments
// For local networks, validators activate quickly (5-10s). If it takes longer,
// something is wrong - fail fast with clear error rather than waiting forever.
@@ -88,7 +89,7 @@ var (
type blockchainInfo struct {
chainName string
vmID ids.ID
chainID ids.ID
chainID ids.ID
blockchainID ids.ID
}
@@ -963,16 +964,16 @@ func (ln *localNetwork) installCustomChains(
// This ensures P-Chain is synchronized across all nodes after blockchain creation
// TEMPORARILY DISABLED - debugging P-Chain sync issue
/*
blockchainIDs := make([]ids.ID, len(blockchainTxs))
for i, tx := range blockchainTxs {
blockchainIDs[i] = tx.ID()
}
if err := ln.waitForBlockchainOnPChain(ctx, blockchainIDs); err != nil {
ln.logger.Error("installCustomChains: P-Chain sync failed",
"error", err.Error(),
)
return nil, fmt.Errorf("P-Chain sync failed: %w", err)
}
blockchainIDs := make([]ids.ID, len(blockchainTxs))
for i, tx := range blockchainTxs {
blockchainIDs[i] = tx.ID()
}
if err := ln.waitForBlockchainOnPChain(ctx, blockchainIDs); err != nil {
ln.logger.Error("installCustomChains: P-Chain sync failed",
"error", err.Error(),
)
return nil, fmt.Errorf("P-Chain sync failed: %w", err)
}
*/
// Nodes need to be restarted after blockchain creation to discover the new chains
@@ -1032,7 +1033,7 @@ func (ln *localNetwork) installCustomChains(
// as there is no way to recover VM name from VM ID
chainName: chainSpec.VMName,
vmID: vmID,
chainID: chainID,
chainID: chainID,
blockchainID: blockchainTxs[i].ID(),
}
}
@@ -1435,9 +1436,9 @@ func newWallet(
}
pTXs[id] = tx
}
pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, luxState.UTXOs)
pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, luxState.UTXOs)
xChainID := luxState.XCTX.BlockchainID
xUTXOs := common.NewChainUTXOs(xChainID, luxState.UTXOs)
xUTXOs := common.NewChainUTXOs(xChainID, luxState.UTXOs)
var w wallet
w.addr = privKey.PublicKey().Address()
// TODO: Create owners map instead of pTXs
+71 -34
View File
@@ -13,10 +13,11 @@ import (
"path/filepath"
"time"
"github.com/luxfi/const"
"maps"
constants "github.com/luxfi/const"
"github.com/luxfi/crypto/bls"
"github.com/luxfi/crypto/bls/signer/localsigner"
"github.com/luxfi/node/vms/platformvm/signer"
luxcrypto "github.com/luxfi/crypto/secp256k1"
"github.com/luxfi/genesis/configs"
"github.com/luxfi/ids"
@@ -25,7 +26,7 @@ import (
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/node/config"
"maps"
"github.com/luxfi/node/vms/platformvm/signer"
"github.com/luxfi/node/staking"
"github.com/luxfi/node/utils/formatting/address"
@@ -267,12 +268,10 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
m["allocations"] = mustJSON(newAllocations)
}
// Check if we need to generate initialStakers
var existingStakers []interface{}
if raw, ok := m["initialStakers"]; ok {
json.Unmarshal(raw, &existingStakers)
}
if len(existingStakers) == 0 {
// ALWAYS replace initialStakers with embedded validator keys for local network testing.
// The genesis file may have different validators than netrunner's embedded keys,
// so we must replace them to ensure nodes can actually validate.
{
// Generate initialStakers from embedded validator keys
var generatedStakers []map[string]interface{}
for i := uint32(0); i < numEmbeddedToUse; i++ {
@@ -423,6 +422,10 @@ func NewCanonicalCustomConfig(binaryPath string, numNodes uint32) (network.Confi
// newCanonicalConfig creates a network config with canonical (pre-serialized) genesis bytes
// and loads validator keys from ~/.lux/keys/node{0..n-1}/
//
// IMPORTANT: This function patches the genesis initialStakers with the BLS keys from the
// loaded validator keys. This ensures the validators' BLS Proof of Possession (PoP) in genesis
// matches the actual signer.key files the nodes will use.
func newCanonicalConfig(binaryPath string, numNodes uint32, networkID uint32, portBase int) (network.Config, error) {
// Load CANONICAL genesis bytes - no parsing/re-serialization
originalGenesisBytes, err := configs.GetCanonicalGenesisBytes(networkID)
@@ -430,13 +433,61 @@ func newCanonicalConfig(binaryPath string, numNodes uint32, networkID uint32, po
return network.Config{}, fmt.Errorf("failed to load canonical genesis: %w", err)
}
// For LOCAL TESTING: Update startTime to now so bootstrap starts immediately.
// Load validator keys from ~/.lux/keys/ FIRST so we can patch genesis with them
keysDir := os.Getenv("LUX_KEYS_DIR")
if keysDir == "" {
keysDir = validatorKeysDir()
}
ks := keys.NewKeyStore(keysDir)
// Load all validator keys and build initialStakers
hrp := constants.GetHRP(networkID)
validatorKeys := make([]*keys.ValidatorKey, numNodes)
initialStakers := make([]map[string]interface{}, numNodes)
for i := uint32(0); i < numNodes; i++ {
name := fmt.Sprintf("node%d", i)
vk, err := ks.Load(name)
if err != nil {
return network.Config{}, fmt.Errorf("failed to load validator key %s from %s: %w (run 'lux key generate' first)", name, keysDir, err)
}
validatorKeys[i] = vk
// Build initialStaker entry with BLS keys from loaded validator
rewardAddr, err := address.Format("P", hrp, vk.PChainAddr[:])
if err != nil {
return network.Config{}, fmt.Errorf("couldn't format reward address for node %d: %w", i, err)
}
staker := map[string]interface{}{
"nodeID": vk.NodeID.String(),
"rewardAddress": rewardAddr,
"delegationFee": 20000,
"weight": GigaLux, // 1 billion nLUX = 1000 LUX
}
if len(vk.BLSPublicKey) > 0 && len(vk.BLSPoP) > 0 {
staker["signer"] = map[string]interface{}{
"publicKey": vk.BLSPublicKeyHex(),
"proofOfPossession": vk.BLSPoPHex(),
}
fmt.Printf(" Validator %d: %s (BLS: %s...)\n", i, vk.NodeID.String(), vk.BLSPublicKeyHex()[:20])
} else {
fmt.Printf(" Validator %d: %s (no BLS key)\n", i, vk.NodeID.String())
}
initialStakers[i] = staker
}
// For LOCAL TESTING: Update startTime to now AND patch initialStakers with our keys
// CRITICAL: Use patchGenesisPreservingRaw to preserve cChainGenesis exact bytes.
now := time.Now().Unix()
fmt.Printf("📅 Updated genesis startTime to %d (now) for local testing\n", now)
fmt.Printf("🔑 Patching genesis initialStakers with %d validators from %s\n", numNodes, keysDir)
genesisBytes, err := patchGenesisPreservingRaw(originalGenesisBytes, evmGenesisKeys, func(m map[string]json.RawMessage) error {
m["startTime"] = mustJSON(uint64(now))
m["initialStakers"] = mustJSON(initialStakers)
return nil
})
if err != nil {
@@ -447,22 +498,10 @@ func newCanonicalConfig(binaryPath string, numNodes uint32, networkID uint32, po
netConfig := NewDefaultConfig(binaryPath)
netConfig.Genesis = string(genesisBytes)
// Load validator keys from ~/.lux/keys/
keysDir := os.Getenv("LUX_KEYS_DIR")
if keysDir == "" {
keysDir = validatorKeysDir()
}
ks := keys.NewKeyStore(keysDir)
// Load keys for each node
// Build node configs from loaded keys
nodeConfigs := make([]node.Config, numNodes)
for i := uint32(0); i < numNodes; i++ {
name := fmt.Sprintf("node%d", i)
vk, err := ks.Load(name)
if err != nil {
return network.Config{}, fmt.Errorf("failed to load validator key %s from %s: %w (run 'lux key generate' first)", name, keysDir, err)
}
vk := validatorKeys[i]
port := portBase + int(i)*2
nodeConfigs[i] = node.Config{
Flags: map[string]interface{}{
@@ -477,11 +516,10 @@ func newCanonicalConfig(binaryPath string, numNodes uint32, networkID uint32, po
UpgradeConfigFiles: map[string]string{},
PChainConfigFiles: map[string]string{},
}
fmt.Printf(" Loaded validator %d: %s\n", i, vk.NodeID.String())
}
netConfig.NodeConfigs = nodeConfigs
fmt.Printf("✅ Loaded canonical genesis for network %d with %d validators\n", networkID, numNodes)
fmt.Printf("✅ Loaded canonical genesis for network %d with %d validators (BLS keys patched)\n", networkID, numNodes)
return netConfig, nil
}
@@ -724,13 +762,13 @@ func NewConfigWithPreExistingKeys(binaryPath string, networkID uint32, keysDir s
config.HTTPPortKey: port,
config.StakingPortKey: port + 1,
},
StakingKey: string(vk.StakerKey),
StakingCert: string(vk.StakerCert),
StakingSigningKey: base64.StdEncoding.EncodeToString(vk.BLSSecretKey),
IsBeacon: true,
ChainConfigFiles: map[string]string{},
StakingKey: string(vk.StakerKey),
StakingCert: string(vk.StakerCert),
StakingSigningKey: base64.StdEncoding.EncodeToString(vk.BLSSecretKey),
IsBeacon: true,
ChainConfigFiles: map[string]string{},
UpgradeConfigFiles: map[string]string{},
PChainConfigFiles: map[string]string{},
PChainConfigFiles: map[string]string{},
}
}
@@ -1016,8 +1054,7 @@ func NewConfigFromMnemonic(binaryPath string, networkID uint32, numNodes uint32)
// Add per-node specific flags
nodeFlags[config.HTTPPortKey] = port
nodeFlags[config.StakingPortKey] = port + 1
// Enable sybil protection for mainnet - validators have proper keys
// The genesis validators have matching NodeIDs from deterministic TLS certs
// Sybil protection MUST be enabled - validators come from genesis initialStakers
nodeFlags[config.SybilProtectionEnabledKey] = true
netConfig.NodeConfigs[i] = node.Config{
+1 -1
View File
@@ -11,7 +11,7 @@ import (
"path/filepath"
"time"
"github.com/luxfi/const"
constants "github.com/luxfi/const"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/utils"
+1 -1
View File
@@ -13,9 +13,9 @@ import (
"time"
"github.com/luxfi/genesis/configs"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
"github.com/luxfi/netrunner/local"
"github.com/stretchr/testify/require"
)
+53 -53
View File
@@ -1,72 +1,72 @@
package local
import (
"fmt"
"os"
"testing"
"fmt"
"os"
"testing"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg"
"github.com/luxfi/go-bip39"
luxcrypto "github.com/luxfi/crypto/secp256k1"
"golang.org/x/crypto/sha3"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg"
luxcrypto "github.com/luxfi/crypto/secp256k1"
"github.com/luxfi/go-bip39"
"golang.org/x/crypto/sha3"
)
func TestMnemonicDerivation(t *testing.T) {
mnemonic := os.Getenv("LUX_MNEMONIC")
if mnemonic == "" {
t.Skip("LUX_MNEMONIC not set")
}
mnemonic := os.Getenv("LUX_MNEMONIC")
if mnemonic == "" {
t.Skip("LUX_MNEMONIC not set")
}
fmt.Printf("Mnemonic: %s...\n", mnemonic[:20])
fmt.Printf("Mnemonic: %s...\n", mnemonic[:20])
if !bip39.IsMnemonicValid(mnemonic) {
t.Fatal("Invalid mnemonic")
}
if !bip39.IsMnemonicValid(mnemonic) {
t.Fatal("Invalid mnemonic")
}
seed := bip39.NewSeed(mnemonic, "")
seed := bip39.NewSeed(mnemonic, "")
// Derive using BIP44 m/44'/60'/0'/0/0
masterKey, _ := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
purpose, _ := masterKey.Derive(hdkeychain.HardenedKeyStart + 44)
coinType, _ := purpose.Derive(hdkeychain.HardenedKeyStart + 60)
account, _ := coinType.Derive(hdkeychain.HardenedKeyStart + 0)
change, _ := account.Derive(0)
addressKey, _ := change.Derive(0)
// Derive using BIP44 m/44'/60'/0'/0/0
masterKey, _ := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
purpose, _ := masterKey.Derive(hdkeychain.HardenedKeyStart + 44)
coinType, _ := purpose.Derive(hdkeychain.HardenedKeyStart + 60)
account, _ := coinType.Derive(hdkeychain.HardenedKeyStart + 0)
change, _ := account.Derive(0)
addressKey, _ := change.Derive(0)
ecPrivKey, _ := addressKey.ECPrivKey()
privKeyBytes := ecPrivKey.Serialize()
ecPrivKey, _ := addressKey.ECPrivKey()
privKeyBytes := ecPrivKey.Serialize()
privKey, err := luxcrypto.ToPrivateKey(privKeyBytes)
if err != nil {
t.Fatalf("Error: %v", err)
}
pubKey := privKey.PublicKey()
shortID := pubKey.Address()
privKey, err := luxcrypto.ToPrivateKey(privKeyBytes)
if err != nil {
t.Fatalf("Error: %v", err)
}
pubKey := privKey.PublicKey()
shortID := pubKey.Address()
// Get Ethereum address
pubKeyBytes := pubKey.Bytes()
hash := sha3.NewLegacyKeccak256()
hash.Write(pubKeyBytes[1:]) // skip the 0x04 prefix
ethAddr := hash.Sum(nil)[12:]
// Get Ethereum address
pubKeyBytes := pubKey.Bytes()
hash := sha3.NewLegacyKeccak256()
hash.Write(pubKeyBytes[1:]) // skip the 0x04 prefix
ethAddr := hash.Sum(nil)[12:]
fmt.Printf("\n=== Key Derivation Results (m/44'/60'/0'/0/0) ===\n")
fmt.Printf("Lux Short ID: %s\n", shortID.String())
fmt.Printf("Ethereum Address: 0x%x\n", ethAddr)
fmt.Printf("Expected Treasury: 0x9011E888251AB053B7bD1cdB598Db4f9DEd94714\n")
fmt.Printf("\n=== Key Derivation Results (m/44'/60'/0'/0/0) ===\n")
fmt.Printf("Lux Short ID: %s\n", shortID.String())
fmt.Printf("Ethereum Address: 0x%x\n", ethAddr)
fmt.Printf("Expected Treasury: 0x9011E888251AB053B7bD1cdB598Db4f9DEd94714\n")
// Also derive using coin type 9000 for comparison
coinType9000, _ := purpose.Derive(hdkeychain.HardenedKeyStart + 9000)
account9000, _ := coinType9000.Derive(hdkeychain.HardenedKeyStart + 0)
change9000, _ := account9000.Derive(0)
addressKey9000, _ := change9000.Derive(0)
ecPrivKey9000, _ := addressKey9000.ECPrivKey()
privKey9000, _ := luxcrypto.ToPrivateKey(ecPrivKey9000.Serialize())
shortID9000 := privKey9000.PublicKey().Address()
// Also derive using coin type 9000 for comparison
coinType9000, _ := purpose.Derive(hdkeychain.HardenedKeyStart + 9000)
account9000, _ := coinType9000.Derive(hdkeychain.HardenedKeyStart + 0)
change9000, _ := account9000.Derive(0)
addressKey9000, _ := change9000.Derive(0)
ecPrivKey9000, _ := addressKey9000.ECPrivKey()
privKey9000, _ := luxcrypto.ToPrivateKey(ecPrivKey9000.Serialize())
shortID9000 := privKey9000.PublicKey().Address()
fmt.Printf("\n=== Comparison: Coin Type 9000 (m/44'/9000'/0'/0/0) ===\n")
fmt.Printf("Lux Short ID (9000): %s\n", shortID9000.String())
fmt.Printf("\n=== Comparison: Coin Type 9000 (m/44'/9000'/0'/0/0) ===\n")
fmt.Printf("Lux Short ID (9000): %s\n", shortID9000.String())
fmt.Printf("\n=== Genesis Treasury P-chain Address ===\n")
fmt.Printf("Expected: P-lux1jqg73zp9r2c98daarnd4nrd5l80dj3c5eha5fl\n")
fmt.Printf("\n=== Genesis Treasury P-chain Address ===\n")
fmt.Printf("Expected: P-lux1jqg73zp9r2c98daarnd4nrd5l80dj3c5eha5fl\n")
}
+23 -22
View File
@@ -19,6 +19,9 @@ import (
"sync"
"time"
"maps"
"slices"
luxconfig "github.com/luxfi/config"
"github.com/luxfi/crypto/bls"
luxcrypto "github.com/luxfi/crypto/secp256k1"
@@ -36,8 +39,6 @@ import (
"github.com/luxfi/node/network/peer"
"github.com/luxfi/node/staking"
"github.com/luxfi/node/utils/beacon"
"maps"
"slices"
"github.com/luxfi/node/utils/formatting/address"
"github.com/luxfi/node/utils/wrappers"
@@ -55,12 +56,12 @@ const (
genesisFileName = "genesis.json"
stopTimeout = 30 * time.Second
// healthCheckFreq reduced from 3s to 1s for faster health polling
healthCheckFreq = 1 * time.Second
DefaultNumNodes = 5
snapshotPrefix = "lux-snapshot-"
networkRootDirPrefix = "network"
defaultDBSubdir = "db"
defaultLogsSubdir = "logs"
healthCheckFreq = 1 * time.Second
DefaultNumNodes = 5
snapshotPrefix = "lux-snapshot-"
networkRootDirPrefix = "network"
defaultDBSubdir = "db"
defaultLogsSubdir = "logs"
// difference between unlock schedule locktime and startime in original genesis
genesisLocktimeStartimeDelta = 2836800
)
@@ -75,8 +76,8 @@ var (
config.BootstrapIPsKey: {},
config.BootstrapIDsKey: {},
}
chainConfigSubDir = "chainConfigs"
pChainConfigSubDir = "pChainConfigs"
chainConfigSubDir = "chainConfigs"
pChainConfigSubDir = "pChainConfigs"
snapshotsRelPath = filepath.Join(".netrunner", "snapshots")
@@ -85,7 +86,7 @@ var (
// network keeps information uses for network management, and accessing all the nodes
type localNetwork struct {
lock sync.RWMutex
lock sync.RWMutex
logger log.Logger
// This network's ID.
networkID uint32
@@ -261,7 +262,7 @@ func init() {
"C": string(cChainConfig),
},
UpgradeConfigFiles: map[string]string{},
PChainConfigFiles: map[string]string{},
PChainConfigFiles: map[string]string{},
}
for i := 0; i < len(defaultNetworkConfig.NodeConfigs); i++ {
@@ -366,16 +367,16 @@ func newNetwork(
}
// Create the network
net := &localNetwork{
nextNodeSuffix: 1,
nodes: map[string]*localNode{},
onStopCh: make(chan struct{}),
logger: logger,
bootstraps: beacon.NewSet(),
newAPIClientF: newAPIClientF,
nodeProcessCreator: nodeProcessCreator,
rootDir: rootDir,
snapshotsDir: snapshotsDir,
reassignPortsIfUsed: reassignPortsIfUsed,
nextNodeSuffix: 1,
nodes: map[string]*localNode{},
onStopCh: make(chan struct{}),
logger: logger,
bootstraps: beacon.NewSet(),
newAPIClientF: newAPIClientF,
nodeProcessCreator: nodeProcessCreator,
rootDir: rootDir,
snapshotsDir: snapshotsDir,
reassignPortsIfUsed: reassignPortsIfUsed,
chainID2ElasticChainID: map[ids.ID]ids.ID{},
}
return net, nil
+14 -14
View File
@@ -13,6 +13,8 @@ import (
"testing"
"time"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/api"
apimocks "github.com/luxfi/netrunner/api/mocks"
"github.com/luxfi/netrunner/local/mocks"
@@ -23,10 +25,8 @@ import (
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/node/api/health"
"github.com/luxfi/node/config"
"github.com/luxfi/ids"
"github.com/luxfi/node/message"
"github.com/luxfi/node/network/peer"
"github.com/luxfi/log"
"github.com/luxfi/node/utils/rpc"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -38,12 +38,12 @@ const (
)
var (
_ NodeProcessCreator = &localTestSuccessfulNodeProcessCreator{}
_ NodeProcessCreator = &localTestFailedStartProcessCreator{}
_ NodeProcessCreator = &localTestProcessUndefNodeProcessCreator{}
_ NodeProcessCreator = &localTestFlagCheckProcessCreator{}
_ api.NewAPIClientF = newMockAPISuccessful
_ api.NewAPIClientF = newMockAPIUnhealthy
_ NodeProcessCreator = &localTestSuccessfulNodeProcessCreator{}
_ NodeProcessCreator = &localTestFailedStartProcessCreator{}
_ NodeProcessCreator = &localTestProcessUndefNodeProcessCreator{}
_ NodeProcessCreator = &localTestFlagCheckProcessCreator{}
_ api.NewAPIClientF = newMockAPISuccessful
_ api.NewAPIClientF = newMockAPIUnhealthy
_ peer.InboundHandler = &noOpInboundHandler{}
)
@@ -1185,9 +1185,9 @@ func TestWriteFiles(t *testing.T) {
config.StakingTLSKeyPathKey: stakingKeyPath,
config.StakingCertPathKey: stakingCertPath,
config.StakingSignerKeyPathKey: stakingSigningKeyPath,
config.GenesisFileKey: genesisPath,
config.GenesisFileKey: genesisPath,
config.ChainConfigDirKey: chainConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.NetConfigDirKey: subnetConfigDir,
},
},
{
@@ -1203,9 +1203,9 @@ func TestWriteFiles(t *testing.T) {
config.StakingTLSKeyPathKey: stakingKeyPath,
config.StakingCertPathKey: stakingCertPath,
config.StakingSignerKeyPathKey: stakingSigningKeyPath,
config.GenesisFileKey: genesisPath,
config.GenesisFileKey: genesisPath,
config.ChainConfigDirKey: chainConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.ConfigFileKey: configFilePath,
},
},
@@ -1223,9 +1223,9 @@ func TestWriteFiles(t *testing.T) {
config.StakingTLSKeyPathKey: stakingKeyPath,
config.StakingCertPathKey: stakingCertPath,
config.StakingSignerKeyPathKey: stakingSigningKeyPath,
config.GenesisFileKey: genesisPath,
config.GenesisFileKey: genesisPath,
config.ChainConfigDirKey: chainConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.ConfigFileKey: configFilePath,
},
},
+8 -8
View File
@@ -9,23 +9,23 @@ import (
"net/netip"
"time"
validators "github.com/luxfi/consensus/validator" // package name is validators
constants "github.com/luxfi/const"
"github.com/luxfi/crypto/bls"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/math/set"
"github.com/luxfi/metric"
"github.com/luxfi/netrunner/api"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/network/node/status"
"github.com/luxfi/const"
"github.com/luxfi/ids"
"github.com/luxfi/node/message"
"github.com/luxfi/node/network/peer"
"github.com/luxfi/node/network/throttling"
"github.com/luxfi/node/network/tracker"
"github.com/luxfi/node/utils/compression"
"github.com/luxfi/consensus/validator" // package name is validators
"github.com/luxfi/node/staking"
"github.com/luxfi/node/utils"
"github.com/luxfi/crypto/bls"
"github.com/luxfi/log"
"github.com/luxfi/math/set"
"github.com/luxfi/metric"
"github.com/luxfi/node/utils/compression"
"github.com/luxfi/node/version"
"github.com/prometheus/client_golang/prometheus"
)
+5 -5
View File
@@ -8,10 +8,10 @@ import (
"os/exec"
"sync"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/network/node/status"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/log"
"github.com/shirou/gopsutil/process"
)
@@ -81,10 +81,10 @@ func (npc *nodeProcessCreator) NewNodeProcess(config node.Config, args ...string
}
type nodeProcess struct {
name string
logger log.Logger
lock sync.RWMutex
cmd *exec.Cmd
name string
logger log.Logger
lock sync.RWMutex
cmd *exec.Cmd
// Process status
state status.Status
// Closed when the process exits.
+3 -5
View File
@@ -15,18 +15,16 @@ import (
"testing"
"time"
"github.com/luxfi/netrunner/network/node"
constants "github.com/luxfi/const"
"github.com/luxfi/geth/metrics"
"github.com/luxfi/ids"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/node/message"
"github.com/luxfi/node/network/peer"
"github.com/luxfi/node/staking"
"github.com/luxfi/const"
"github.com/luxfi/node/utils/ips"
luxlog "github.com/luxfi/log"
"github.com/luxfi/node/utils/wrappers"
"github.com/luxfi/node/version"
"github.com/luxfi/metric"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
)
+4 -3
View File
@@ -9,16 +9,17 @@ import (
"path/filepath"
"strings"
"maps"
"slices"
luxconfig "github.com/luxfi/config"
"github.com/luxfi/const"
constants "github.com/luxfi/const"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/api"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/utils"
"maps"
"slices"
"github.com/luxfi/node/config"
dircopy "github.com/otiai10/copy"
+29 -29
View File
@@ -9,9 +9,9 @@ import (
"time"
"github.com/dgraph-io/badger/v4"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/netrunner/network"
)
// NetworkType represents the type of network
@@ -19,29 +19,29 @@ type NetworkType string
const (
NetworkTypePrimary NetworkType = "primary" // Mainnet or Testnet
NetworkTypeChain NetworkType = "chain" // L1/L2 chains
NetworkTypeChain NetworkType = "chain" // L1/L2 chains
)
// NetworkConfig defines configuration for a single network
type NetworkConfig struct {
NetworkID uint32 `json:"networkID"`
Name string `json:"name"`
Type NetworkType `json:"type"`
ParentID uint32 `json:"parentID,omitempty"` // For chains
HTTPPort int `json:"httpPort"`
StakingPort int `json:"stakingPort"`
DataDir string `json:"dataDir"`
Validators int `json:"validators"`
NetworkID uint32 `json:"networkID"`
Name string `json:"name"`
Type NetworkType `json:"type"`
ParentID uint32 `json:"parentID,omitempty"` // For chains
HTTPPort int `json:"httpPort"`
StakingPort int `json:"stakingPort"`
DataDir string `json:"dataDir"`
Validators int `json:"validators"`
ChainConfig []ChainConfig `json:"chains,omitempty"`
}
// ChainConfig defines configuration for a chain within a network
type ChainConfig struct {
ChainID string `json:"chainID"`
VMID string `json:"vmID"`
PChainID string `json:"pChainID,omitempty"`
Genesis []byte `json:"genesis,omitempty"`
IsEVM bool `json:"isEVM"`
ChainID string `json:"chainID"`
VMID string `json:"vmID"`
PChainID string `json:"pChainID,omitempty"`
Genesis []byte `json:"genesis,omitempty"`
IsEVM bool `json:"isEVM"`
}
// MultiNetworkManager manages multiple networks running in parallel
@@ -73,7 +73,7 @@ type NetworkInstance struct {
Config NetworkConfig
Network network.Network
Status NetworkStatus
Chains map[string]*ChainInstance
Chains map[string]*ChainInstance
StartTime time.Time
}
@@ -107,13 +107,13 @@ type ConsensusManager struct {
// ConsensusParams defines consensus parameters
type ConsensusParams struct {
K int `json:"k"`
Alpha int `json:"alpha"`
BetaVirtuous int `json:"betaVirtuous"`
BetaRogue int `json:"betaRogue"`
ConcurrentPolls int `json:"concurrentPolls"`
OptimalProcessing int `json:"optimalProcessing"`
MaxProcessing int `json:"maxProcessing"`
K int `json:"k"`
Alpha int `json:"alpha"`
BetaVirtuous int `json:"betaVirtuous"`
BetaRogue int `json:"betaRogue"`
ConcurrentPolls int `json:"concurrentPolls"`
OptimalProcessing int `json:"optimalProcessing"`
MaxProcessing int `json:"maxProcessing"`
MaxTimeProcessing time.Duration `json:"maxTimeProcessing"`
}
@@ -146,10 +146,10 @@ type CrossChainTx struct {
type TxStatus string
const (
TxStatusPending TxStatus = "pending"
TxStatusPending TxStatus = "pending"
TxStatusValidating TxStatus = "validating"
TxStatusCommitted TxStatus = "committed"
TxStatusFailed TxStatus = "failed"
TxStatusCommitted TxStatus = "committed"
TxStatusFailed TxStatus = "failed"
)
// NewMultiNetworkManager creates a new multi-network manager
@@ -170,7 +170,7 @@ func NewMultiNetworkManager(logger log.Logger, sharedDBPath string) (*MultiNetwo
networks: make(map[uint32]*NetworkInstance),
consensusManagers: make(map[uint32]*ConsensusManager),
txCoordinator: NewCrossChainTxCoordinator(sharedDB),
logger: logger,
logger: logger,
ctx: ctx,
cancel: cancel,
}, nil
@@ -195,8 +195,8 @@ func (m *MultiNetworkManager) AddNetwork(config NetworkConfig) error {
}
instance := &NetworkInstance{
Config: config,
Status: NetworkStatusStopped,
Config: config,
Status: NetworkStatusStopped,
Chains: make(map[string]*ChainInstance),
}
+5 -4
View File
@@ -8,11 +8,12 @@ import (
"strconv"
"time"
"github.com/luxfi/const"
"maps"
constants "github.com/luxfi/const"
"github.com/luxfi/genesis/pkg/genesis"
"github.com/luxfi/ids"
"github.com/luxfi/netrunner/network/node"
"maps"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/node/utils/formatting/address"
@@ -152,8 +153,8 @@ func NewGenesis(
NetworkID: networkID,
Allocations: []genesis.UnparsedAllocation{
{
ETHAddr: zeroEthAddr, // Zero address as hex string
LUXAddr: genesisVdrStakeAddr, // Bech32 formatted address
ETHAddr: zeroEthAddr, // Zero address as hex string
LUXAddr: genesisVdrStakeAddr, // Bech32 formatted address
InitialAmount: 0,
UnlockSchedule: []genesis.LockedAmount{ // Provides stake to validators
{
+1 -1
View File
@@ -5,8 +5,8 @@ import (
"errors"
"time"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/ids"
"github.com/luxfi/netrunner/network/node"
)
var (
+1 -1
View File
@@ -6,10 +6,10 @@ import (
"errors"
"fmt"
"github.com/luxfi/ids"
"github.com/luxfi/netrunner/api"
"github.com/luxfi/netrunner/network/node/status"
"github.com/luxfi/node/config"
"github.com/luxfi/ids"
"github.com/luxfi/node/network/peer"
)
+10 -10
View File
@@ -16,12 +16,12 @@ import (
// Host manages multiple consensus engines
type Host struct {
mu sync.RWMutex
engines map[string]engines.Engine
ports *PortManager
indexer *Indexer
metrics *MetricsCollector
networks map[string]*NetworkInfo
mu sync.RWMutex
engines map[string]engines.Engine
ports *PortManager
indexer *Indexer
metrics *MetricsCollector
networks map[string]*NetworkInfo
}
// NetworkInfo describes a network's properties
@@ -207,14 +207,14 @@ func (h *Host) StartStack(ctx context.Context, manifest *StackManifest) error {
}
if err := h.StartEngine(ctx, engine.Name, engine.Type, options); err != nil {
// Rollback on failure
h.StopStack(ctx, manifest.Name)
_ = h.StopStack(ctx, manifest.Name)
return fmt.Errorf("failed to start %s: %w", engine.Name, err)
}
// Wait for health before starting dependent engines
if engine.WaitHealthy {
if err := h.waitHealthy(ctx, engine.Name, 30*time.Second); err != nil {
h.StopStack(ctx, manifest.Name)
_ = h.StopStack(ctx, manifest.Name)
return fmt.Errorf("engine %s failed health check: %w", engine.Name, err)
}
}
@@ -424,8 +424,8 @@ func (h *Host) LoadState(path string) error {
// HostState represents the persistent state of the host
type HostState struct {
Engines map[string]*EngineState `json:"engines"`
Networks map[string]*NetworkInfo `json:"networks"`
Engines map[string]*EngineState `json:"engines"`
Networks map[string]*NetworkInfo `json:"networks"`
}
// EngineState represents the state of an engine
+2 -2
View File
@@ -10,8 +10,8 @@ import (
// Indexer provides cross-engine blockchain indexing
type Indexer struct {
mu sync.RWMutex
data map[string]*IndexData
mu sync.RWMutex
data map[string]*IndexData
}
// IndexData contains indexed blockchain data
+15 -15
View File
@@ -15,12 +15,12 @@ import (
// StackManifest defines a multi-engine stack configuration
type StackManifest struct {
Name string `yaml:"name" json:"name"`
Version string `yaml:"version" json:"version"`
Description string `yaml:"description" json:"description"`
Engines []EngineConfig `yaml:"engines" json:"engines"`
Bridge *BridgeConfig `yaml:"bridge,omitempty" json:"bridge,omitempty"`
Networks []NetworkConfig `yaml:"networks,omitempty" json:"networks,omitempty"`
Name string `yaml:"name" json:"name"`
Version string `yaml:"version" json:"version"`
Description string `yaml:"description" json:"description"`
Engines []EngineConfig `yaml:"engines" json:"engines"`
Bridge *BridgeConfig `yaml:"bridge,omitempty" json:"bridge,omitempty"`
Networks []NetworkConfig `yaml:"networks,omitempty" json:"networks,omitempty"`
}
// EngineConfig defines an engine configuration
@@ -40,21 +40,21 @@ type EngineConfig struct {
DependsOn []string `yaml:"depends_on,omitempty" json:"depends_on,omitempty"`
// OP Stack specific
L1RPC string `yaml:"l1_rpc,omitempty" json:"l1_rpc,omitempty"`
Sequencer bool `yaml:"sequencer,omitempty" json:"sequencer,omitempty"`
L1RPC string `yaml:"l1_rpc,omitempty" json:"l1_rpc,omitempty"`
Sequencer bool `yaml:"sequencer,omitempty" json:"sequencer,omitempty"`
// Eth2 specific
ConsensusClient string `yaml:"consensus_client,omitempty" json:"consensus_client,omitempty"`
ExecutionClient string `yaml:"execution_client,omitempty" json:"execution_client,omitempty"`
ValidatorEnabled bool `yaml:"validator_enabled,omitempty" json:"validator_enabled,omitempty"`
ConsensusClient string `yaml:"consensus_client,omitempty" json:"consensus_client,omitempty"`
ExecutionClient string `yaml:"execution_client,omitempty" json:"execution_client,omitempty"`
ValidatorEnabled bool `yaml:"validator_enabled,omitempty" json:"validator_enabled,omitempty"`
}
// BridgeConfig defines bridge configuration between engines
type BridgeConfig struct {
Type string `yaml:"type" json:"type"` // awm, ibc, ccip
Source string `yaml:"source" json:"source"`
Destination string `yaml:"destination" json:"destination"`
RelayerKey string `yaml:"relayer_key,omitempty" json:"relayer_key,omitempty"`
Type string `yaml:"type" json:"type"` // awm, ibc, ccip
Source string `yaml:"source" json:"source"`
Destination string `yaml:"destination" json:"destination"`
RelayerKey string `yaml:"relayer_key,omitempty" json:"relayer_key,omitempty"`
Contracts map[string]string `yaml:"contracts,omitempty" json:"contracts,omitempty"`
}
+4 -4
View File
@@ -11,10 +11,10 @@ import (
// PortManager manages port allocation for engines
type PortManager struct {
mu sync.Mutex
allocated map[uint16]bool
httpBase uint16
p2pBase uint16
mu sync.Mutex
allocated map[uint16]bool
httpBase uint16
p2pBase uint16
}
// NewPortManager creates a new port manager
+4 -3
View File
@@ -7,12 +7,13 @@
package rpcpb
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
+1
View File
@@ -8,6 +8,7 @@ package rpcpb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
+22 -21
View File
@@ -13,6 +13,10 @@ import (
"strings"
"sync"
"maps"
"slices"
"github.com/luxfi/ids"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
@@ -20,9 +24,6 @@ import (
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/netrunner/ux"
"github.com/luxfi/node/config"
"github.com/luxfi/ids"
"maps"
"slices"
luxd_constants "github.com/luxfi/const"
"github.com/luxfi/log"
@@ -80,7 +81,7 @@ type localNetwork struct {
type chainInfo struct {
info *rpcpb.CustomChainInfo
chainID ids.ID
chainID ids.ID
blockchainID ids.ID
}
@@ -88,7 +89,7 @@ type localNetworkOptions struct {
execPath string
rootDataDir string
numNodes uint32
trackChains string
trackChains string
redirectNodesOutput bool
globalNodeConfig string
@@ -132,7 +133,7 @@ func newLocalNetwork(opts localNetworkOptions) (*localNetwork, error) {
customChainIDToInfo: make(map[ids.ID]chainInfo),
stopCh: make(chan struct{}),
nodeInfos: make(map[string]*rpcpb.NodeInfo),
chains: make(map[string]*rpcpb.ChainInfo),
chains: make(map[string]*rpcpb.ChainInfo),
}, nil
}
@@ -705,12 +706,12 @@ func (lc *localNetwork) updateChainInfo(ctx context.Context) error {
}
lc.customChainIDToInfo[blockchain.ID] = chainInfo{
info: &rpcpb.CustomChainInfo{
ChainName: blockchain.Name,
VmId: blockchain.VMID.String(),
PchainId: blockchain.NetID.String(),
BlockchainId: blockchain.ID.String(),
ChainName: blockchain.Name,
VmId: blockchain.VMID.String(),
PchainId: blockchain.NetID.String(),
BlockchainId: blockchain.ID.String(),
},
chainID: blockchain.NetID,
chainID: blockchain.NetID,
blockchainID: blockchain.ID,
}
}
@@ -758,7 +759,7 @@ func (lc *localNetwork) updateChainInfo(ctx context.Context) error {
}
lc.chains[chainIDStr] = &rpcpb.ChainInfo{
IsElastic: isElastic,
IsElastic: isElastic,
ElasticChainId: elasticChainID.String(),
ChainParticipants: &rpcpb.ChainParticipants{NodeNames: nodeNameList},
}
@@ -858,16 +859,16 @@ func (lc *localNetwork) updateNodeInfo() error {
}
lc.nodeInfos[name] = &rpcpb.NodeInfo{
Name: node.GetName(),
Uri: node.GetURL(),
Id: node.GetNodeID().String(),
ExecPath: node.GetBinaryPath(),
LogDir: node.GetLogsDir(),
DbDir: node.GetDbDir(),
Config: []byte(node.GetConfigFile()),
PluginDir: node.GetPluginDir(),
Name: node.GetName(),
Uri: node.GetURL(),
Id: node.GetNodeID().String(),
ExecPath: node.GetBinaryPath(),
LogDir: node.GetLogsDir(),
DbDir: node.GetDbDir(),
Config: []byte(node.GetConfigFile()),
PluginDir: node.GetPluginDir(),
WhitelistedChains: trackChains,
Paused: node.GetPaused(),
Paused: node.GetPaused(),
}
// update default exec and pluginDir if empty (snapshots started without these params)
+22 -21
View File
@@ -21,6 +21,11 @@ import (
"go.uber.org/multierr"
"maps"
"slices"
"github.com/luxfi/consensus/core"
"github.com/luxfi/ids"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/rpcpb"
@@ -28,15 +33,11 @@ import (
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/node/config"
"github.com/luxfi/node/message"
"github.com/luxfi/consensus/core"
"github.com/luxfi/node/network/peer"
"github.com/luxfi/ids"
"maps"
"slices"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/luxfi/log"
"github.com/luxfi/math/set"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
@@ -51,8 +52,8 @@ const (
MinNodes uint32 = 1
DefaultNodes uint32 = 5
stopTimeout = 5 * time.Second
defaultStartTimeout = 5 * time.Minute
stopTimeout = 5 * time.Second
defaultStartTimeout = 5 * time.Minute
// waitForHealthyTimeout - 60s for local 5-node network bootstrap
// First startup takes longer as nodes need to establish consensus
// Subsequent restarts are faster (<10s) but initial bootstrap needs time
@@ -75,9 +76,9 @@ var (
ErrNodeNotFound = errors.New("node not found")
ErrPeerNotFound = errors.New("peer not found")
ErrStatusCanceled = errors.New("gRPC stream status canceled")
ErrNoChainSpec = errors.New("no blockchain spec was provided")
ErrNoChainID = errors.New("chainID is missing")
ErrNoElasticChainSpec = errors.New("no elastic chain spec was provided")
ErrNoChainSpec = errors.New("no blockchain spec was provided")
ErrNoChainID = errors.New("chainID is missing")
ErrNoElasticChainSpec = errors.New("no elastic chain spec was provided")
ErrNoValidatorSpec = errors.New("no validator spec was provided")
)
@@ -175,7 +176,7 @@ type Server interface {
type server struct {
mu *sync.RWMutex
cfg Config
cfg Config
logger log.Logger
rootCtx context.Context
@@ -221,7 +222,7 @@ func New(cfg Config, logger log.Logger) (Server, error) {
s := &server{
cfg: cfg,
logger: logger,
logger: logger,
closed: make(chan struct{}),
ln: listener,
gRPCServer: grpc.NewServer(),
@@ -381,7 +382,7 @@ func (s *server) Start(_ context.Context, req *rpcpb.StartRequest) (*rpcpb.Start
var (
execPath = req.GetExecPath()
numNodes = req.GetNumNodes()
trackChains = req.GetWhitelistedChains()
trackChains = req.GetWhitelistedChains()
rootDataDir = req.GetRootDataDir()
pid = int32(os.Getpid())
globalNodeConfig = req.GetGlobalNodeConfig()
@@ -410,7 +411,7 @@ func (s *server) Start(_ context.Context, req *rpcpb.StartRequest) (*rpcpb.Start
} else {
// CLI provided a specific rootDataDir - use it directly
// Trust the CLI to provide a properly structured path
networkName = getNetworkNameFromRootDir(rootDataDir)
_ = getNetworkNameFromRootDir(rootDataDir)
// Ensure the provided directory exists
if err = os.MkdirAll(rootDataDir, os.ModePerm); err != nil {
@@ -432,7 +433,7 @@ func (s *server) Start(_ context.Context, req *rpcpb.StartRequest) (*rpcpb.Start
execPath: execPath,
rootDataDir: rootDataDir,
numNodes: numNodes,
trackChains: trackChains,
trackChains: trackChains,
redirectNodesOutput: s.cfg.RedirectNodesOutput,
pluginDir: pluginDir,
globalNodeConfig: globalNodeConfig,
@@ -1278,7 +1279,7 @@ var _ peer.InboundHandler = &loggingInboundHandler{}
type loggingInboundHandler struct {
nodeName string
logger log.Logger
logger log.Logger
}
func (lh *loggingInboundHandler) HandleInbound(_ context.Context, msg message.InboundMessage) {
@@ -1601,7 +1602,7 @@ func getNetworkElasticChainSpec(
maxStakeDuration := time.Duration(spec.MaxStakeDuration) * time.Hour
elasticParticipantsSpec := network.ElasticChainSpec{
ChainID: &spec.ChainId,
ChainID: &spec.ChainId,
AssetName: spec.AssetName,
AssetSymbol: spec.AssetSymbol,
InitialSupply: spec.InitialSupply,
@@ -1638,7 +1639,7 @@ func getPermissionlessValidatorSpec(
stakeDuration := time.Duration(spec.StakeDuration) * time.Hour
validatorSpec := network.PermissionlessValidatorSpec{
ChainID: spec.ChainId,
ChainID: spec.ChainId,
AssetID: spec.AssetId,
NodeName: spec.NodeName,
StakedAmount: spec.StakedTokenAmount,
@@ -1652,7 +1653,7 @@ func getRemoveChainValidatorSpec(
spec *rpcpb.RemoveChainValidatorSpec,
) network.RemoveChainValidatorSpec {
validatorSpec := network.RemoveChainValidatorSpec{
ChainID: spec.ChainId,
ChainID: spec.ChainId,
NodeNames: spec.GetNodeNames(),
}
return validatorSpec
@@ -1730,13 +1731,13 @@ func getNetworkChainSpec(
PerNodeChainConfig: perNodeChainConfig,
// Use BlockchainAlias as the blockchain name for the P-Chain transaction
// This allows multiple chains to use the same VM (e.g., multiple EVM chains)
BlockchainName: spec.BlockchainAlias,
BlockchainName: spec.BlockchainAlias,
}
if spec.ChainSpec != nil {
participantsSpec := network.ParticipantsSpec{
Participants: spec.ChainSpec.Participants,
ChainConfig: chainConfigBytes,
ChainConfig: chainConfigBytes,
}
chainSpec.ParticipantsSpec = &participantsSpec
}
+16 -15
View File
@@ -17,23 +17,24 @@ import (
"testing"
"time"
"github.com/luxfi/node/api/admin"
"github.com/luxfi/node/message"
luxd_constants "github.com/luxfi/const"
"maps"
"slices"
luxd_constants "github.com/luxfi/const"
"github.com/luxfi/node/api/admin"
"github.com/luxfi/node/message"
"github.com/luxfi/node/vms/platformvm"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/metric"
"github.com/luxfi/netrunner/client"
"github.com/luxfi/netrunner/rpcpb"
"github.com/luxfi/netrunner/server"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/netrunner/ux"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/metric"
ginkgo "github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
)
@@ -55,7 +56,7 @@ var (
gRPCGatewayEp string
execPath1 string
execPath2 string
evmPath string
evmPath string
genesisPath string
genesisContents string
@@ -332,8 +333,8 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
resp, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
{
VmName: "evm",
Genesis: genesisContents,
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: subnetParticipants},
},
},
@@ -364,8 +365,8 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
resp, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
{
VmName: "evm",
Genesis: genesisContents,
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: subnetParticipants2},
},
},
@@ -423,13 +424,13 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
resp, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
{
VmName: "evm",
Genesis: genesisContents,
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewSubnetParticipants[0]},
},
{
VmName: "evm",
Genesis: genesisContents,
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewSubnetParticipants[1]},
},
},
+7 -7
View File
@@ -12,16 +12,16 @@ const (
// Network run directory structure (flat, no nesting)
// Structure: ~/.lux/runs/<networkName>/run_<timestamp>/node1/, node2/, ...
RunsDir = "runs" // Top-level runs directory
RunDirPrefix = "run" // Prefix for timestamped run directories
DefaultNetwork = "local" // Default network name
RunsDir = "runs" // Top-level runs directory
RunDirPrefix = "run" // Prefix for timestamped run directories
DefaultNetwork = "local" // Default network name
// Unified chain config directory (shared across all nodes)
// Structure: ~/.lux/chains/<chainName>/genesis.json, config.json, upgrade.json
ChainsDir = "chains"
ChainGenesisFile = "genesis.json"
ChainConfigFile = "config.json"
ChainUpgradeFile = "upgrade.json"
ChainsDir = "chains"
ChainGenesisFile = "genesis.json"
ChainConfigFile = "config.json"
ChainUpgradeFile = "upgrade.json"
// Unified plugins directory
// Structure: ~/.lux/plugins/current/<vmid> (symlinks to actual binaries)
+2 -2
View File
@@ -8,11 +8,11 @@ import (
"os"
"time"
"github.com/luxfi/ids"
"github.com/luxfi/log"
rpcb "github.com/luxfi/netrunner/rpcpb"
"github.com/luxfi/netrunner/ux"
"github.com/luxfi/ids"
"github.com/luxfi/node/staking"
"github.com/luxfi/log"
)
const (