mirror of
https://github.com/luxfi/netrunner.git
synced 2026-07-27 00:04:23 +00:00
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:
+38
-101
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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 ""
|
||||
}
|
||||
}())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/luxfi/log"
|
||||
"fmt"
|
||||
|
||||
"github.com/luxfi/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/luxfi/log"
|
||||
"fmt"
|
||||
|
||||
"github.com/luxfi/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/luxfi/log"
|
||||
"fmt"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/luxfi/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
||||
@@ -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
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -5,8 +5,8 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/netrunner/network/node"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/netrunner/network/node"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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"`
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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 (
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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]},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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
@@ -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 (
|
||||
|
||||
Reference in New Issue
Block a user