fix build

This commit is contained in:
Zach Kelling
2026-01-14 19:56:11 -08:00
parent deae88ca44
commit 160e25c144
49 changed files with 410 additions and 382 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
## Project Overview
Lux Netrunner is a powerful network orchestration and testing framework for blockchain development. It provides comprehensive tools for creating, managing, and testing multi-node blockchain networks with support for custom VMs, subnets, and complex network topologies.
Lux Netrunner is a powerful network orchestration and testing framework for blockchain development. It provides comprehensive tools for creating, managing, and testing multi-node blockchain networks with support for custom VMs, chains (L2 blockchains), and complex network topologies.
## Essential Commands
+12 -12
View File
@@ -155,8 +155,8 @@ netrunner control start \
--global-node-config '{"http-host":"0.0.0.0"}'
```
`--plugin-dir` and `--blockchain-specs` are parameters relevant to subnet operation.
See the [subnet](#network-runner-rpc-server-subnet-evm-example) section for details about how to run subnets.
`--plugin-dir` and `--blockchain-specs` are parameters relevant to chain (L2 blockchain) operation.
See the [chain deployment](#network-runner-rpc-server-subnet-evm-example) section for details about how to run chains.
The network-runner supports node node configuration at different levels.
@@ -299,7 +299,7 @@ curl -X POST -k http://localhost:8081/v1/control/removesnapshot -d '{"snapshot_n
netrunner control remove-snapshot snapshotName
```
To create 1 validated subnet, with all existing nodes as participants (requires network restart):
To create 1 validated network (validator set), with all existing nodes as participants (requires network restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createsubnets -d '[{}]'
@@ -308,7 +308,7 @@ curl -X POST -k http://localhost:8081/v1/control/createsubnets -d '[{}]'
netrunner control create-subnets '[{}]'
```
To create 1 validated subnet, with some of existing nodes as participants (requires network restart):
To create 1 validated network (validator set), with some of existing nodes as participants (requires network restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createsubnets -d '[{"participants": ["node1", "node2"]}]'
@@ -317,7 +317,7 @@ curl -X POST -k http://localhost:8081/v1/control/createsubnets -d '[{"participan
netrunner control create-subnets '[{"participants": ["node1", "node2"]}]'
```
To create 1 validated subnet, with some of existing nodes and another new node as participants (requires network restart):
To create 1 validated network (validator set), with some of existing nodes and another new node as participants (requires network restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createsubnets -d '[{"participants": ["node1", "node2", "testNode"]}]'
@@ -327,7 +327,7 @@ netrunner control create-subnets '[{"participants": ["node1", "node2", "testNode
```
To create N validated subnets (requires network restart):
To create N validated networks (validator sets) (requires network restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createsubnets -d '[{}, {"participants": ["node1", "node2", "node3"]}, {"participants": ["node1", "node2", "testNode"]}]'
@@ -337,7 +337,7 @@ netrunner control create-subnets '[{}, {"participants": ["node1", "node2", "node
```
To create a blockchain without a subnet id (requires network restart):
To create a blockchain without a network id (requires network restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'"}]}'
@@ -355,7 +355,7 @@ curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginD
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_CONTENTS'"}]' --plugin-dir $PLUGIN_DIR
```
To create a blockchain with a subnet id (does not require restart):
To create a blockchain with a network id (does not require restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_id": "'$SUBNET_ID'"}]}'
@@ -364,7 +364,7 @@ curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginD
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_id": "'$SUBNET_ID'"}]' --plugin-dir $PLUGIN_DIR
```
To create a blockchain with a subnet id, and chain config, network upgrade and subnet config file paths (requires network restart):
To create a blockchain with a network id, and chain config, network upgrade and network config file paths (requires network restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_id": "'$SUBNET_ID'", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "subnet_config": "'$SUBNET_CONFIG_PATH'"}]}'
@@ -373,7 +373,7 @@ curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginD
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_id": "'$SUBNET_ID'", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "subnet_config": "'$SUBNET_CONFIG_PATH'"}]' --plugin-dir $PLUGIN_DIR
```
To create a blockchain with a new subnet id with select nodes as participants (requires network restart):
To create a blockchain with a new network id with select nodes as participants (requires network restart):
(New nodes will first be added as primary validators similar to the process in `create-subnets`)
```bash
@@ -383,7 +383,7 @@ curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginD
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_spec": "{"participants": ["node1", "node2", "testNode"]}]' --plugin-dir $PLUGIN_DIR
```
To create two blockchains in two disjoint subnets (not shared validators), and where all validators have bls keys (parcipants new to the network):
To create two blockchains in two disjoint networks (not shared validators), and where all validators have bls keys (participants new to the network):
```bash
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_spec": {"participants": ["new_node1", "new_node2"]}},{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_spec": {"participants": ["new_node3", "new_node4"]}}]'
@@ -666,7 +666,7 @@ netrunner control start \
curl -X POST -k http://localhost:8081/v1/control/status -d ''
```
Blockchain config file, network upgrade file, and subnet config file paths can be optionally specified at network start, eg:
Blockchain config file, network upgrade file, and network config file paths can be optionally specified at network start, eg:
```bash
curl -X POST -k http://localhost:8081/v1/control/start -d '{"execPath":"'${LUXD_EXEC_PATH}'","numNodes":5,"logLevel":"INFO","pluginDir":"'${LUXD_PLUGIN_PATH}'","blockchainSpecs":[{"vm_name":"subnetevm","genesis":"/tmp/subnet-evm.genesis.json","chain_config":"'$CHAIN_CONFIG_PATH'","network_upgrade":"'$NETWORK_UPGRADE_PATH'","subnet_config":"'$SUBNET_CONFIG_PATH'"}]}'
+2 -2
View File
@@ -3,8 +3,8 @@ package api
import (
"fmt"
"github.com/luxfi/vm/vms/exchangevm"
"github.com/luxfi/vm/vms/platformvm"
"github.com/luxfi/sdk/api/exchangevm"
"github.com/luxfi/sdk/api/platformvm"
"github.com/luxfi/sdk/api/admin"
"github.com/luxfi/sdk/api/health"
"github.com/luxfi/sdk/api/indexer"
+2 -2
View File
@@ -7,8 +7,8 @@ import (
ethereum "github.com/luxfi/geth"
"github.com/luxfi/geth/common"
"github.com/luxfi/geth/core/types"
"github.com/luxfi/vm/vms/exchangevm"
"github.com/luxfi/vm/vms/platformvm"
"github.com/luxfi/sdk/api/exchangevm"
"github.com/luxfi/sdk/api/platformvm"
"github.com/luxfi/rpc"
"github.com/luxfi/sdk/api/admin"
"github.com/luxfi/sdk/api/health"
+2 -2
View File
@@ -6,7 +6,7 @@ import (
api "github.com/luxfi/netrunner/api"
admin "github.com/luxfi/sdk/api/admin"
exchangevm "github.com/luxfi/vm/vms/exchangevm"
exchangevm "github.com/luxfi/sdk/api/exchangevm"
indexer "github.com/luxfi/sdk/api/indexer"
@@ -14,7 +14,7 @@ import (
mock "github.com/stretchr/testify/mock"
platformvm "github.com/luxfi/vm/vms/platformvm"
platformvm "github.com/luxfi/sdk/api/platformvm"
)
// Client is an autogenerated mock type for the Client type
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"sync"
"time"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/rpcpb"
"google.golang.org/grpc"
+2 -3
View File
@@ -14,8 +14,7 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/client"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/rpcpb"
@@ -49,7 +48,7 @@ func NewCommand() *cobra.Command {
Short: "Start a network runner controller.",
}
cmd.PersistentFlags().StringVar(&logLevel, "log-level", level.Info.String(), "log level")
cmd.PersistentFlags().StringVar(&logLevel, "log-level", log.InfoLevel.String(), "log level")
cmd.PersistentFlags().StringVar(&logDir, "log-dir", "", "log directory")
cmd.PersistentFlags().StringVar(&endpoint, "endpoint", "0.0.0.0:9000", "server endpoint")
cmd.PersistentFlags().DurationVar(&dialTimeout, "dial-timeout", 10*time.Second, "server dial timeout")
+1 -1
View File
@@ -6,7 +6,7 @@ package commands
import (
"fmt"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/spf13/cobra"
)
+1 -1
View File
@@ -11,7 +11,7 @@ import (
"text/tabwriter"
"time"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/engines"
_ "github.com/luxfi/netrunner/engines/geth"
+1 -1
View File
@@ -6,7 +6,7 @@ package commands
import (
"fmt"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/spf13/cobra"
)
+1 -1
View File
@@ -10,7 +10,7 @@ import (
"text/tabwriter"
"time"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/orchestrator"
"github.com/spf13/cobra"
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"os"
"text/tabwriter"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/spf13/cobra"
)
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"fmt"
"time"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/engines"
"github.com/spf13/cobra"
+2 -3
View File
@@ -10,8 +10,7 @@ import (
"os/signal"
"syscall"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/cmd/netrunner/commands"
"github.com/luxfi/netrunner/cmd/server"
"github.com/spf13/cobra"
@@ -25,7 +24,7 @@ var (
func main() {
// Setup logger - use development logger for console output
logger := log.NewTestLogger(level.Info)
logger := log.NewTestLogger(log.InfoLevel)
// Setup root command
rootCmd := &cobra.Command{
+3 -4
View File
@@ -7,8 +7,7 @@ import (
"context"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/client"
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/netrunner/ux"
@@ -29,7 +28,7 @@ func NewCommand() *cobra.Command {
RunE: pingFunc,
}
cmd.PersistentFlags().StringVar(&logLevel, "log-level", level.Info.String(), "log level")
cmd.PersistentFlags().StringVar(&logLevel, "log-level", log.InfoLevel.String(), "log level")
cmd.PersistentFlags().StringVar(&endpoint, "endpoint", "0.0.0.0:9000", "server endpoint")
cmd.PersistentFlags().DurationVar(&dialTimeout, "dial-timeout", 10*time.Second, "server dial timeout")
cmd.PersistentFlags().DurationVar(&requestTimeout, "request-timeout", 10*time.Second, "client request timeout")
@@ -44,7 +43,7 @@ func pingFunc(*cobra.Command, []string) error {
}
lcfg := log.Config{
DisplayLevel: lvl,
LogLevel: level.Off,
LogLevel: log.Disabled,
}
logFactory := log.NewFactoryWithConfig(lcfg)
logger, err := logFactory.Make(constants.LogNameControl)
+2 -3
View File
@@ -11,8 +11,7 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/server"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/netrunner/utils/constants"
@@ -44,7 +43,7 @@ func NewCommand() *cobra.Command {
Args: cobra.ExactArgs(0),
}
cmd.PersistentFlags().StringVar(&logLevel, "log-level", level.Info.String(), "log level for server logs")
cmd.PersistentFlags().StringVar(&logLevel, "log-level", log.InfoLevel.String(), "log level for server logs")
cmd.PersistentFlags().StringVar(&logDir, "log-dir", "", "log directory")
cmd.PersistentFlags().StringVar(&port, "port", ":9000", "server port")
cmd.PersistentFlags().StringVar(&gwPort, "grpc-gateway-port", ":9001", "grpc-gateway server port")
+7 -7
View File
@@ -40,7 +40,7 @@ type Config struct {
// Upgrade configuration files
UpgradeConfigFiles map[string]string `json:"upgradeConfigFiles"`
// Subnet configuration files
// Network (validator set) configuration files
SubnetConfigFiles map[string]string `json:"subnetConfigFiles"`
}
```
@@ -187,10 +187,10 @@ type BlockchainSpec struct {
// Genesis data (file path or JSON string)
Genesis []byte `json:"genesis"`
// Subnet ID (optional)
// Network ID (optional) - identifies the validator set
SubnetID *string `json:"subnet_id"`
// Subnet specification
// Network specification (validator set configuration)
SubnetSpec *SubnetSpec `json:"subnet_spec"`
// Chain configuration
@@ -304,21 +304,21 @@ type BlockchainSpec struct {
}
```
## Subnet Configuration
## Network Configuration (Validator Sets)
### Subnet Spec Structure
### Network Spec Structure
```go
type SubnetSpec struct {
// Validator participants
Participants []string `json:"participants"`
// Subnet configuration
// Network configuration
SubnetConfig []byte `json:"subnet_config"`
}
```
### Elastic Subnet Configuration
### Elastic Network Configuration
```go
type ElasticSubnetSpec struct {
+9 -9
View File
@@ -5,14 +5,14 @@ description: Lux Netrunner - Network orchestration and testing framework for Lux
# Lux Netrunner
Lux Netrunner is a powerful network orchestration and testing framework designed for blockchain development. It provides comprehensive tools for creating, managing, and testing multi-node blockchain networks with support for custom VMs, subnets, and complex network topologies.
Lux Netrunner is a powerful network orchestration and testing framework designed for blockchain development. It provides comprehensive tools for creating, managing, and testing multi-node blockchain networks with support for custom VMs, chains (L2 blockchains), and complex network topologies.
## Overview
Netrunner simplifies blockchain network testing by providing:
- **Dynamic network management** - Create, modify, and control networks on the fly
- **Multi-chain support** - Deploy and test multiple blockchains simultaneously
- **Subnet orchestration** - Easily create and manage subnets with custom validators
- **Network orchestration** - Easily create and manage networks (validator sets) with custom validators
- **Testing automation** - Built-in support for various testing scenarios
- **Network snapshots** - Save and restore complete network states
- **Chaos engineering** - Simulate failures and network partitions
@@ -106,14 +106,14 @@ netrunner control health --endpoint="0.0.0.0:8080"
netrunner control uris --endpoint="0.0.0.0:8080"
```
### Deploy a Subnet
### Deploy a Chain
```bash
# Create subnet with specific validators
# Create network (validator set) with specific validators
netrunner control create-subnets \
'[{"participants": ["node1", "node2", "node3"]}]'
# Deploy a blockchain on the subnet
# Deploy a blockchain on the network
netrunner control create-blockchains \
'[{
"vm_name": "subnetevm",
@@ -132,7 +132,7 @@ netrunner control create-blockchains \
### Integration Testing
- Multi-chain interaction testing
- Cross-subnet communication
- Cross-chain communication
- API endpoint validation
- Transaction throughput testing
@@ -227,9 +227,9 @@ curl -X POST -k http://localhost:8081/v1/control/savesnapshot -d '{
- `netrunner control resume-node` - Resume a node
- `netrunner control restart-node` - Restart a node
### Subnet Commands
- `netrunner control create-subnets` - Create subnets
- `netrunner control create-blockchains` - Deploy blockchains
### Network Commands
- `netrunner control create-subnets` - Create networks (validator sets)
- `netrunner control create-blockchains` - Deploy blockchains (chains)
### Snapshot Commands
- `netrunner control save-snapshot` - Save network state (stops network)
+12 -12
View File
@@ -13,7 +13,7 @@ Network orchestration in Netrunner allows you to:
- Dynamically create and manage multi-node networks
- Configure node topologies and relationships
- Manage node lifecycle (start, stop, pause, resume)
- Coordinate subnet and blockchain deployments
- Coordinate network (validator set) and blockchain deployments
- Simulate network conditions and failures
## Core Components
@@ -154,21 +154,21 @@ netrunner control pause-node node1
netrunner control resume-node node1
```
## Subnet Orchestration
## Network Orchestration (Validator Sets)
### Creating Subnets
### Creating Networks
Create subnets with specific validators:
Create networks (validator sets) with specific validators:
```bash
# Create subnet with all nodes as validators
# Create network with all nodes as validators
netrunner control create-subnets '[{}]'
# Create subnet with specific validators
# Create network with specific validators
netrunner control create-subnets \
'[{"participants": ["node1", "node2", "node3"]}]'
# Create multiple subnets
# Create multiple networks
netrunner control create-subnets \
'[
{"participants": ["node1", "node2"]},
@@ -176,9 +176,9 @@ netrunner control create-subnets \
]'
```
### Elastic Subnets
### Elastic Networks
Configure elastic subnets with custom parameters:
Configure elastic networks with custom parameters:
```go
type ElasticSubnetSpec struct {
@@ -204,7 +204,7 @@ type ElasticSubnetSpec struct {
### Deploying Custom VMs
Deploy custom virtual machines on subnets:
Deploy custom virtual machines on networks:
```bash
# Deploy a single blockchain
@@ -371,7 +371,7 @@ netrunner control start \
# Wait for network health
netrunner control health --endpoint="0.0.0.0:8080"
# Create a subnet
# Create a network (validator set)
netrunner control create-subnets \
'[{"participants": ["node1", "node2", "node3"]}]'
@@ -398,7 +398,7 @@ netrunner control stop --endpoint="0.0.0.0:8080"
1. **Nodes fail to start**: Check binary path and permissions
2. **Network unhealthy**: Verify port availability and firewall rules
3. **Subnet creation fails**: Ensure sufficient validators
3. **Network creation fails**: Ensure sufficient validators
4. **Snapshot restore fails**: Check disk space and file permissions
### Debug Commands
+15 -15
View File
@@ -5,7 +5,7 @@ description: Complete guide to setting up test networks with Lux Netrunner
# Test Network Setup
This guide walks through setting up various test network configurations using Lux Netrunner, from simple single-node setups to complex multi-subnet deployments.
This guide walks through setting up various test network configurations using Lux Netrunner, from simple single-node setups to complex multi-chain deployments.
## Prerequisites
@@ -146,9 +146,9 @@ netrunner control start \
}'
```
## Subnet Networks
## Validator Networks
### Create a Permissioned Subnet
### Create a Permissioned Network
```bash
# Start the network
@@ -160,7 +160,7 @@ netrunner control start \
# Wait for health
netrunner control health
# Create subnet with all nodes
# Create network with all nodes
netrunner control create-subnets '[{}]'
# Or create with specific validators
@@ -168,13 +168,13 @@ netrunner control create-subnets \
'[{"participants": ["node1", "node2", "node3"]}]'
```
### Create an Elastic Subnet
### Create an Elastic Network
Elastic subnets allow dynamic validator sets:
Elastic networks allow dynamic validator sets:
```bash
# Create elastic subnet configuration
cat > elastic-subnet.json <<EOF
# Create elastic network configuration
cat > elastic-network.json <<EOF
{
"AssetName": "TestToken",
"AssetSymbol": "TEST",
@@ -193,8 +193,8 @@ cat > elastic-subnet.json <<EOF
}
EOF
# Create elastic subnet
netrunner control create-elastic-subnet elastic-subnet.json
# Create elastic network
netrunner control create-elastic-subnet elastic-network.json
```
## Custom Blockchain Deployment
@@ -325,12 +325,12 @@ netrunner control start \
# Wait for bootstrap
netrunner control health
# Create subnet with validators
# Create network (validator set) with validators
netrunner control create-subnets '[{
"participants": ["node1", "node2", "node3"]
}]'
# Get subnet info
# Get network info
netrunner control status
```
@@ -426,7 +426,7 @@ netrunner control start \
--number-of-nodes=5 \
--node-path ${LUXD_EXEC_PATH}
# Create subnets and blockchains
# Create networks (validator sets) and blockchains
netrunner control create-subnets '[{"participants": ["node1", "node2"]}]'
# Save snapshot
@@ -478,8 +478,8 @@ netrunner control health --endpoint=${ENDPOINT}
netrunner control save-snapshot test1-complete
netrunner control stop --endpoint=${ENDPOINT}
# Test 2: Subnet network
echo "Test 2: Subnet deployment"
# Test 2: Network (validator set) deployment
echo "Test 2: Network deployment"
netrunner control load-snapshot test1-complete \
--endpoint=${ENDPOINT}
+10 -10
View File
@@ -193,12 +193,12 @@ IMPORT_TX=$(curl -X POST --data '{
echo "Import TX: ${IMPORT_TX}"
```
### Subnet Testing
### Network Testing
#### Subnet Creation and Validation
#### Network Creation and Validation
```go
func TestSubnetCreation(t *testing.T) {
func TestNetworkCreation(t *testing.T) {
ctx := context.Background()
// Start network
@@ -208,16 +208,16 @@ func TestSubnetCreation(t *testing.T) {
require.NoError(t, err)
defer network.Stop(ctx)
// Create subnet with 3 validators
subnetSpec := &netrunner.SubnetSpec{
// Create network (validator set) with 3 validators
networkSpec := &netrunner.SubnetSpec{
Participants: []string{"node1", "node2", "node3"},
}
subnetID, err := network.CreateSubnet(ctx, subnetSpec)
networkID, err := network.CreateSubnet(ctx, networkSpec)
require.NoError(t, err)
// Verify subnet validators
validators, err := network.GetSubnetValidators(ctx, subnetID)
// Verify network validators
validators, err := network.GetSubnetValidators(ctx, networkID)
require.NoError(t, err)
assert.Len(t, validators, 3)
}
@@ -611,7 +611,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
test: [consensus, subnet, performance, chaos]
test: [consensus, network, performance, chaos]
steps:
- uses: actions/checkout@v2
@@ -685,7 +685,7 @@ run_test() {
# Run all tests
run_test "consensus"
run_test "subnet"
run_test "network"
run_test "performance"
run_test "chaos"
run_test "upgrade"
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
)
+3 -4
View File
@@ -9,8 +9,7 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
)
@@ -48,8 +47,8 @@ func shutdownOnSignal(
func main() {
// Create the logger
logFactory := log.NewFactoryWithConfig(log.Config{
DisplayLevel: level.Info,
LogLevel: level.Debug,
DisplayLevel: log.InfoLevel,
LogLevel: log.DebugLevel,
})
logger, err := logFactory.Make("main")
if err != nil {
+3 -4
View File
@@ -9,8 +9,7 @@ import (
"time"
"github.com/luxfi/config"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
@@ -56,8 +55,8 @@ func shutdownOnSignal(
func main() {
// Create the logger
logFactory := log.NewFactoryWithConfig(log.Config{
DisplayLevel: level.Info,
LogLevel: level.Debug,
DisplayLevel: log.InfoLevel,
LogLevel: log.DebugLevel,
})
logger, err := logFactory.Make("main")
if err != nil {
+3 -4
View File
@@ -12,8 +12,7 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/node/config"
@@ -107,8 +106,8 @@ func shutdownOnSignal(
func main() {
logFactory := log.NewFactoryWithConfig(log.Config{
DisplayLevel: level.Info,
LogLevel: level.Debug,
DisplayLevel: log.InfoLevel,
LogLevel: log.DebugLevel,
})
logger, err := logFactory.Make("l2chains")
if err != nil {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
)
+99 -44
View File
@@ -9,7 +9,7 @@ import (
"syscall"
"time"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/luxfi/netrunner/network"
)
@@ -35,50 +35,88 @@ func shutdownOnSignal(
close(closedOnShutdownChan)
}
// Zoo chain genesis for testnet (chain ID 200201)
func createZooTestnetGenesis() ([]byte, error) {
zooGenesis := map[string]interface{}{
"alloc": map[string]interface{}{
"0200000000000000000000000000000000000005": map[string]interface{}{
"balance": "0x0",
"nonce": "0x1",
"code": "0x01",
},
"9011E888251AB053B7bD1cdB598Db4f9DEd94714": map[string]interface{}{
"balance": "0x193e5939a08ce9dbd480000000",
},
},
"baseFeePerGas": "0x5d21dba00",
"config": map[string]interface{}{
"berlinBlock": 0,
"byzantiumBlock": 0,
"chainId": 200201, // Testnet chain ID
"constantinopleBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"homesteadBlock": 0,
"istanbulBlock": 0,
"londonBlock": 0,
"petersburgBlock": 0,
"subnetEVMTimestamp": 0,
"durangoTimestamp": 0,
"feeConfig": map[string]interface{}{
"gasLimit": 12000000,
"targetBlockRate": 2,
"minBaseFee": 25000000000,
"targetGas": 15000000,
"baseFeeChangeDenominator": 36,
"minBlockGasCost": 0,
"maxBlockGasCost": 1000000,
"blockGasCostStep": 200000,
},
},
"difficulty": "0x0",
"gasLimit": "0xb71b00",
"timestamp": "0x6727e9c3",
data, err := os.ReadFile("/Users/z/work/lux/genesis/configs/zoo-testnet/genesis.json")
if err != nil {
return nil, err
}
return json.Marshal(zooGenesis)
return activateEVMUpgrades(data)
}
func createCorethDebugConfig(importPath string) ([]byte, error) {
cfg := map[string]interface{}{
"admin-api-enabled": true,
"eth-apis": []string{
"eth",
"eth-filter",
"net",
"web3",
"debug",
"internal-eth",
"internal-blockchain",
"internal-transaction",
"internal-account",
"admin",
},
"import-chain-data": importPath,
"log-level": "debug",
}
return json.Marshal(cfg)
}
func activateEVMUpgrades(genesisJSON []byte) ([]byte, error) {
// Force all upgrade timestamps to 0 so upgrades are active at genesis.
var genesis map[string]interface{}
if err := json.Unmarshal(genesisJSON, &genesis); err != nil {
return nil, err
}
if cfg, ok := genesis["config"].(map[string]interface{}); ok {
for _, key := range []string{
"banffBlockTimestamp",
"cortinaBlockTimestamp",
"durangoTimestamp",
"durangoBlockTimestamp",
"etnaTimestamp",
"fortunaTimestamp",
"graniteTimestamp",
"cancunTime",
"shanghaiTime",
} {
if _, exists := cfg[key]; exists {
cfg[key] = 0
}
}
}
return json.Marshal(genesis)
}
func activateCChainUpgrades(genesisJSON string) (string, error) {
var top map[string]json.RawMessage
if err := json.Unmarshal([]byte(genesisJSON), &top); err != nil {
return "", err
}
raw, ok := top["cChainGenesis"]
if !ok {
return genesisJSON, nil
}
var cChainGenesis string
if err := json.Unmarshal(raw, &cChainGenesis); err != nil {
return "", err
}
updated, err := activateEVMUpgrades([]byte(cChainGenesis))
if err != nil {
return "", err
}
updatedRaw, err := json.Marshal(string(updated))
if err != nil {
return "", err
}
top["cChainGenesis"] = updatedRaw
out, err := json.Marshal(top)
if err != nil {
return "", err
}
return string(out), nil
}
func main() {
@@ -109,6 +147,18 @@ func run(logger log.Logger, binaryPath string) error {
if err != nil {
return fmt.Errorf("failed to create testnet config: %w", err)
}
updatedGenesis, err := activateCChainUpgrades(netConfig.Genesis)
if err != nil {
return fmt.Errorf("failed to activate C-chain upgrades: %w", err)
}
netConfig.Genesis = updatedGenesis
netConfig.Flags["track-all-chains"] = true
corethConfig, err := createCorethDebugConfig("/Users/z/work/lux/state/rlp/lux-testnet/lux-testnet-96368.rlp")
if err != nil {
return fmt.Errorf("failed to create coreth debug config: %w", err)
}
netConfig.ChainConfigFiles["C"] = string(corethConfig)
// Override ports to avoid conflict with mainnet (use 9640-9649)
// and update bootstrap IPs/ports accordingly
@@ -116,6 +166,7 @@ func run(logger log.Logger, binaryPath string) error {
for i := range netConfig.NodeConfigs {
netConfig.NodeConfigs[i].Flags["http-port"] = 9640 + (i * 2)
netConfig.NodeConfigs[i].Flags["staking-port"] = 9641 + (i * 2)
netConfig.NodeConfigs[i].Flags["track-all-chains"] = true
// Update bootstrap ports for non-beacon nodes
if !netConfig.NodeConfigs[i].IsBeacon {
@@ -168,12 +219,16 @@ func run(logger log.Logger, binaryPath string) error {
if err != nil {
return fmt.Errorf("failed to create zoo testnet genesis: %w", err)
}
zooCorethConfig, err := createCorethDebugConfig("/Users/z/work/lux/state/rlp/zoo-testnet/zoo-testnet-200201.rlp")
if err != nil {
return fmt.Errorf("failed to create zoo testnet coreth config: %w", err)
}
zooChainSpec := []network.ChainSpec{
{
VMName: "evm",
Genesis: zooGenesis,
ChainConfig: nil,
ChainConfig: zooCorethConfig,
BlockchainName: "zootest",
},
}
+9 -9
View File
@@ -59,8 +59,8 @@ engines:
- eth2-settlement
wait_healthy: true
# ZOO L2 on Lux
- name: zoo-subnet
# ZOO L2 Chain on Lux
- name: zoo-chain
type: lux
binary: "subnet-evm"
network_id: 200200
@@ -69,13 +69,13 @@ engines:
extra:
chain_id: 200200
parent_chain: lux-mainnet
subnet_id: "2ebCneCbwthjQ1rYT41nhd7M76Hc6YmosMAQrTFhBq8qeqh6tt"
network_id: "2ebCneCbwthjQ1rYT41nhd7M76Hc6YmosMAQrTFhBq8qeqh6tt"
depends_on:
- lux-mainnet
wait_healthy: true
# SPC L2 on Lux
- name: spc-subnet
# SPC L2 Chain on Lux
- name: spc-chain
type: lux
binary: "subnet-evm"
network_id: 36911
@@ -84,7 +84,7 @@ engines:
extra:
chain_id: 36911
parent_chain: lux-mainnet
subnet_id: "2ebCneCbwthjQ1rYT41nhd7M76Hc6YmosMAQrTFhBq8qeqh6tt"
network_id: "2ebCneCbwthjQ1rYT41nhd7M76Hc6YmosMAQrTFhBq8qeqh6tt"
depends_on:
- lux-mainnet
wait_healthy: true
@@ -135,16 +135,16 @@ networks:
- name: zoo
type: l2
engine: zoo-subnet
engine: zoo-chain
parent: lux
chain_id: 200200
endpoints:
- "http://localhost:9640"
- "ws://localhost:9641"
- name: spc
type: l2
engine: spc-subnet
engine: spc-chain
parent: lux
chain_id: 36911
endpoints:
+8
View File
@@ -163,3 +163,11 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
)
replace (
github.com/luxfi/atomic => ../atomic
github.com/luxfi/consensus => ../consensus
github.com/luxfi/protocol => ../protocol
github.com/luxfi/genesis => ../genesis
github.com/luxfi/log => github.com/luxfi/logger v1.3.1
)
+14 -14
View File
@@ -21,10 +21,10 @@ import (
"github.com/luxfi/keys"
"github.com/luxfi/genesis/pkg/genesis"
"github.com/luxfi/vm/vms/platformvm/reward"
"github.com/luxfi/protocol/p/reward"
"github.com/luxfi/sdk/wallet/chain/x"
"github.com/luxfi/vm/components/lux"
"github.com/luxfi/utxo"
"github.com/luxfi/vm/components/verify"
"maps"
@@ -36,18 +36,18 @@ import (
"github.com/luxfi/crypto/bls"
"github.com/luxfi/crypto/secp256k1"
"github.com/luxfi/ids"
"github.com/luxfi/log"
log "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"
"github.com/luxfi/vm/vms/platformvm"
"github.com/luxfi/vm/vms/platformvm/txs"
"github.com/luxfi/protocol/p/txs"
"github.com/luxfi/protocol/p/signer"
"github.com/luxfi/sdk/api/admin"
"github.com/luxfi/sdk/api/platformvm"
pwallet "github.com/luxfi/sdk/wallet/chain/p"
pwalletwallet "github.com/luxfi/sdk/wallet/chain/p/wallet"
"github.com/luxfi/vm/platformvm/signer"
"github.com/luxfi/vm/secp256k1fx"
"github.com/luxfi/utxo/secp256k1fx"
pbuilder "github.com/luxfi/sdk/wallet/chain/p/builder"
psigner "github.com/luxfi/sdk/wallet/chain/p/signer"
@@ -861,10 +861,10 @@ func (ln *localNetwork) installCustomChains(
return nil, fmt.Errorf("timeout waiting for primary validators: %w", err)
}
// Wait for subnet creation transactions to be fully committed before adding validators
// The P-Chain needs time to commit the subnet creation blocks and propagate state to all nodes
// Wait for chain creation transactions to be fully committed before adding validators
// The P-Chain needs time to commit the chain creation blocks and propagate state to all nodes
// For local networks with fast consensus (K=5), 500ms is sufficient
ln.logger.Info("waiting for subnet creation to be committed...")
ln.logger.Info("waiting for chain creation to be committed...")
time.Sleep(500 * time.Millisecond)
if err = ln.addChainValidators(ctx, platformCli, w, chainIDs, participantsSpecs); err != nil {
@@ -938,7 +938,7 @@ func (ln *localNetwork) installCustomChains(
ln.logger.Info("blockchain created",
"index", i,
"blockchainID", blockchainID.String(),
"subnetID", *chainSpecs[i].ChainID,
"chainID", *chainSpecs[i].ChainID,
)
}
@@ -1549,9 +1549,9 @@ func exportXChainToPChain(ctx context.Context, w *wallet, owner *secp256k1fx.Out
defer cancel()
_, err := w.xWallet.IssueExportTx(
ids.Empty,
[]*lux.TransferableOutput{
[]*utxo.TransferableOutput{
{
Asset: lux.Asset{
Asset: utxo.Asset{
ID: chainAssetID,
},
Out: &secp256k1fx.TransferOutput{
@@ -1942,7 +1942,7 @@ func createChains(
log.Info("creating chain tx")
// Use different variable name to avoid shadowing outer context
txCtx, txCancel := createDefaultCtx(ctx)
tx, err := w.pWallet.IssueCreateSubnetTx(
tx, err := w.pWallet.IssueCreateNetworkTx(
&secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{w.addr},
+12
View File
@@ -10,5 +10,17 @@
"old_name": "whitelisted-subnets",
"new_name": "track-chains",
"value_map": ""
},
{
"version": "v1.9.6",
"old_name": "track-subnets",
"new_name": "track-chains",
"value_map": ""
},
{
"version": "v1.9.6",
"old_name": "subnet-config-dir",
"new_name": "net-config-dir",
"value_map": ""
}
]
+3 -3
View File
@@ -26,7 +26,7 @@ import (
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/utils"
"github.com/luxfi/vm/platformvm/signer"
"github.com/luxfi/protocol/p/signer"
"github.com/luxfi/address"
luxtls "github.com/luxfi/tls"
@@ -35,7 +35,7 @@ import (
// patchGenesisPreservingRaw patches a top-level genesis JSON document while guaranteeing that
// selected keys are preserved byte-for-byte as raw JSON values (including quotes/escapes for strings).
//
// This is the correct approach for EVM genesis fields (C-Chain + any subnet EVM genesis) because
// This is the correct approach for EVM genesis fields (C-Chain + any chain EVM genesis) because
// parsing via interface{} will corrupt large numeric fields and/or change encoding.
//
// CRITICAL: Never use map[string]interface{} for genesis - it causes float64 precision loss!
@@ -101,7 +101,7 @@ func mustJSON(v any) json.RawMessage {
// These correspond to EVM chain genesis configurations.
var evmGenesisKeys = []string{
"cChainGenesis",
// Add subnet EVM genesis keys if embedded in main genesis:
// Add chain EVM genesis keys if embedded in main genesis:
// "hanzoGenesis", "spcGenesis", "zooGenesis",
}
+1 -1
View File
@@ -13,7 +13,7 @@ import (
"github.com/luxfi/config"
"github.com/luxfi/constants"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/utils"
)
+5 -6
View File
@@ -13,8 +13,7 @@ import (
"time"
"github.com/luxfi/genesis/configs"
"github.com/luxfi/log"
"github.com/luxfi/log/level"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/local"
"github.com/stretchr/testify/require"
)
@@ -109,8 +108,8 @@ func TestMainnetFiveNodeNetwork(t *testing.T) {
// Create logger
logFactory := log.NewFactoryWithConfig(log.Config{
DisplayLevel: level.Info,
LogLevel: level.Debug,
DisplayLevel: log.InfoLevel,
LogLevel: log.DebugLevel,
})
log, err := logFactory.Make("test")
require.NoError(t, err, "Failed to create logger")
@@ -156,8 +155,8 @@ func TestMainnetConsensusValidation(t *testing.T) {
// Create logger
logFactory := log.NewFactoryWithConfig(log.Config{
DisplayLevel: level.Info,
LogLevel: level.Debug,
DisplayLevel: log.InfoLevel,
LogLevel: log.DebugLevel,
})
log, err := logFactory.Make("test")
require.NoError(t, err, "Failed to create logger")
+3 -3
View File
@@ -28,7 +28,7 @@ import (
luxcrypto "github.com/luxfi/crypto/secp256k1"
"github.com/luxfi/ids"
"github.com/luxfi/keys"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/math/set"
"github.com/luxfi/netrunner/api"
"github.com/luxfi/netrunner/network"
@@ -38,10 +38,10 @@ import (
"github.com/luxfi/netrunner/utils/constants"
"github.com/luxfi/p2p/peer"
luxtls "github.com/luxfi/tls"
"github.com/luxfi/vm/utils/beacon"
"github.com/luxfi/node/utils/beacon"
"github.com/luxfi/address"
"github.com/luxfi/vm/utils/wrappers"
"github.com/luxfi/node/utils/wrappers"
"golang.org/x/mod/semver"
"golang.org/x/sync/errgroup"
)
+9 -6
View File
@@ -15,7 +15,7 @@ import (
"github.com/luxfi/config"
"github.com/luxfi/ids"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/api"
apimocks "github.com/luxfi/netrunner/api/mocks"
"github.com/luxfi/netrunner/local/mocks"
@@ -898,7 +898,10 @@ func TestChildCmdRedirection(t *testing.T) {
// and it should have a specific length:
// the actual output + the color terminal escape sequence + node name + []<space> + color terminal reset escape sequence
expectedLen := len(expectedResult) + len(utils.NewColorPicker().NextColor()) + len(mockNodeName) + 3 + len(log.Reset)
// color.Wrap("") returns the color escape + reset escape sequences
color := utils.NewColorPicker().NextColor()
colorOverhead := len(color.Wrap(""))
expectedLen := len(expectedResult) + colorOverhead + len(mockNodeName) + 3
if len(result) != expectedLen {
t.Fatalf("expected string length to be %d, but it was %d", expectedLen, len(result))
}
@@ -1161,7 +1164,7 @@ func TestWriteFiles(t *testing.T) {
genesisPath := filepath.Join(tmpDir, genesisFileName)
configFilePath := filepath.Join(tmpDir, configFileName)
chainConfigDir := filepath.Join(tmpDir, chainConfigSubDir)
subnetConfigDir := filepath.Join(tmpDir, pChainConfigSubDir)
networkConfigDir := filepath.Join(tmpDir, pChainConfigSubDir)
cChainConfigPath := filepath.Join(tmpDir, chainConfigSubDir, "C", configFileName)
type test struct {
@@ -1187,7 +1190,7 @@ func TestWriteFiles(t *testing.T) {
config.StakingSignerKeyPathKey: stakingSigningKeyPath,
config.GenesisFileKey: genesisPath,
config.ChainConfigDirKey: chainConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.NetConfigDirKey: networkConfigDir,
},
},
{
@@ -1205,7 +1208,7 @@ func TestWriteFiles(t *testing.T) {
config.StakingSignerKeyPathKey: stakingSigningKeyPath,
config.GenesisFileKey: genesisPath,
config.ChainConfigDirKey: chainConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.NetConfigDirKey: networkConfigDir,
config.ConfigFileKey: configFilePath,
},
},
@@ -1225,7 +1228,7 @@ func TestWriteFiles(t *testing.T) {
config.StakingSignerKeyPathKey: stakingSigningKeyPath,
config.GenesisFileKey: genesisPath,
config.ChainConfigDirKey: chainConfigDir,
config.NetConfigDirKey: subnetConfigDir,
config.NetConfigDirKey: networkConfigDir,
config.ConfigFileKey: configFilePath,
},
},
+8 -9
View File
@@ -9,11 +9,12 @@ import (
"net/netip"
"time"
validators "github.com/luxfi/consensus/validator" // package name is validators
"github.com/luxfi/atomic"
"github.com/luxfi/compress"
"github.com/luxfi/constants"
"github.com/luxfi/crypto/bls"
"github.com/luxfi/ids"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/math/set"
"github.com/luxfi/metric"
"github.com/luxfi/netrunner/api"
@@ -24,10 +25,8 @@ import (
"github.com/luxfi/p2p/throttling"
"github.com/luxfi/p2p/tracker"
luxtls "github.com/luxfi/tls"
validators "github.com/luxfi/validators" // package name is validators
"github.com/luxfi/version"
"github.com/luxfi/vm/utils"
"github.com/luxfi/vm/utils/compression"
"github.com/prometheus/client_golang/prometheus"
)
var (
@@ -102,8 +101,8 @@ func (node *localNode) AttachPeer(ctx context.Context, router peer.InboundHandle
return nil, err
}
mc, err := message.NewCreator(
prometheus.NewRegistry(),
compression.TypeZstd,
metric.NewRegistry(),
compress.TypeZstd,
10*time.Second,
)
if err != nil {
@@ -111,14 +110,14 @@ func (node *localNode) AttachPeer(ctx context.Context, router peer.InboundHandle
}
metrics, err := peer.NewMetrics(
prometheus.NewRegistry(),
metric.NewRegistry(),
)
if err != nil {
return nil, err
}
// Use a nil resource tracker for now - this is acceptable for netrunner testing
var resourceTracker tracker.ResourceTracker = nil
signerIP := utils.NewAtomic(netip.AddrPortFrom(netip.IPv6Unspecified(), 0))
signerIP := atomic.NewAtomic(netip.AddrPortFrom(netip.IPv6Unspecified(), 0))
tls := tlsCert.PrivateKey.(crypto.Signer)
// Create a dummy BLS signer for now
blsKey, err := bls.NewSecretKey()
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"os/exec"
"sync"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/network/node"
"github.com/luxfi/netrunner/network/node/status"
"github.com/luxfi/netrunner/utils"
+2 -2
View File
@@ -23,8 +23,8 @@ import (
"github.com/luxfi/p2p/peer"
luxtls "github.com/luxfi/tls"
"github.com/luxfi/version"
"github.com/luxfi/vm/utils/ips"
"github.com/luxfi/vm/utils/wrappers"
"github.com/luxfi/node/utils/ips"
"github.com/luxfi/node/utils/wrappers"
"github.com/stretchr/testify/require"
)
+1 -1
View File
@@ -17,7 +17,7 @@ import (
luxconfig "github.com/luxfi/config"
"github.com/luxfi/constants"
"github.com/luxfi/ids"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/api"
"github.com/luxfi/netrunner/network"
"github.com/luxfi/netrunner/network/node"
+2 -2
View File
@@ -6,8 +6,8 @@ package local
import (
"context"
"github.com/luxfi/vm/vms/platformvm"
"github.com/luxfi/vm/vms/platformvm/txs"
"github.com/luxfi/protocol/p/txs"
"github.com/luxfi/sdk/api/platformvm"
pwalletwallet "github.com/luxfi/sdk/wallet/chain/p/wallet"
"github.com/luxfi/sdk/wallet/primary/common"
)
+1 -1
View File
@@ -10,7 +10,7 @@ import (
"github.com/dgraph-io/badger/v4"
"github.com/luxfi/ids"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/netrunner/network"
)
+8 -7
View File
@@ -26,7 +26,7 @@ import (
"github.com/luxfi/netrunner/ux"
"github.com/luxfi/constants"
"github.com/luxfi/log"
log "github.com/luxfi/log"
)
const (
@@ -712,10 +712,10 @@ func (lc *localNetwork) updateChainInfo(ctx context.Context) error {
info: &rpcpb.CustomChainInfo{
ChainName: blockchain.Name,
VmId: blockchain.VMID.String(),
PchainId: blockchain.NetID.String(),
PchainId: blockchain.ChainID.String(),
BlockchainId: blockchain.ID.String(),
},
chainID: blockchain.NetID,
chainID: blockchain.ChainID,
blockchainID: blockchain.ID,
}
}
@@ -755,10 +755,11 @@ func (lc *localNetwork) updateChainInfo(ctx context.Context) error {
isElastic := false
elasticChainID := ids.Empty
if _, _, err := (*pChainClient).GetCurrentSupply(ctx, chainID); err == nil {
isElastic = true
elasticChainID, err = lc.nw.GetElasticChainID(ctx, chainID)
if err != nil {
return err
// Only mark as elastic if we can get the elastic chain ID
// (chain must have been transformed via IssueTransformChainTx)
if eid, err := lc.nw.GetElasticChainID(ctx, chainID); err == nil {
isElastic = true
elasticChainID = eid
}
}
+2 -44
View File
@@ -25,8 +25,6 @@ import (
"slices"
"github.com/luxfi/config"
"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"
@@ -36,7 +34,7 @@ import (
"github.com/luxfi/p2p/peer"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/math/set"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
@@ -59,7 +57,7 @@ const (
// Subsequent restarts are faster (<10s) but initial bootstrap needs time
waitForHealthyTimeout = 60 * time.Second
// chainDeployTimeout - time for chain deploy operations including node restarts
// Subnet creation, chain creation, node restart, and P-chain sync can take 60-90s
// Chain creation, node restart, and P-chain sync can take 60-90s
chainDeployTimeout = 120 * time.Second
TimeParseLayout = "2006-01-02 15:04:05"
@@ -1373,46 +1371,6 @@ func (lh *loggingInboundHandler) HandleInbound(_ context.Context, msg message.In
)
}
func (lh *loggingInboundHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, appRequestBytes []byte) error {
lh.logger.Debug(
"AppRequest received",
log.String("node-name", lh.nodeName),
log.Stringer("nodeID", nodeID),
log.Uint32("requestID", requestID),
)
return nil
}
func (lh *loggingInboundHandler) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *core.AppError) error {
lh.logger.Debug(
"AppRequestFailed received",
log.String("node-name", lh.nodeName),
log.Stringer("nodeID", nodeID),
log.Uint32("requestID", requestID),
)
return nil
}
func (lh *loggingInboundHandler) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, appResponseBytes []byte) error {
lh.logger.Debug(
"AppResponse received",
log.String("node-name", lh.nodeName),
log.Stringer("nodeID", nodeID),
log.Uint32("requestID", requestID),
)
return nil
}
func (lh *loggingInboundHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, appGossipBytes []byte) error {
lh.logger.Debug(
"AppGossip received",
log.String("node-name", lh.nodeName),
log.Stringer("nodeID", nodeID),
log.Int("gossipSize", len(appGossipBytes)),
)
return nil
}
func (s *server) AttachPeer(ctx context.Context, req *rpcpb.AttachPeerRequest) (*rpcpb.AttachPeerResponse, error) {
s.mu.Lock()
defer s.mu.Unlock()
+117 -117
View File
@@ -24,10 +24,10 @@ import (
"github.com/luxfi/p2p/message"
"github.com/luxfi/sdk/api/admin"
"github.com/luxfi/vm/vms/platformvm"
"github.com/luxfi/sdk/api/platformvm"
"github.com/luxfi/ids"
"github.com/luxfi/log"
log "github.com/luxfi/log"
"github.com/luxfi/metric"
"github.com/luxfi/netrunner/client"
"github.com/luxfi/netrunner/rpcpb"
@@ -65,9 +65,9 @@ var (
newNode2NodeID = ""
pausedNodeURI = ""
pausedNodeName = "node1"
createdSubnetID = ""
createdNetworkID = ""
elasticAssetID = ""
newSubnetID = ""
newNetworkID = ""
customNodeConfigs = map[string]string{
"node1": `{"api-admin-enabled":true}`,
"node2": `{"api-admin-enabled":true}`,
@@ -78,11 +78,11 @@ var (
"node7": `{"api-admin-enabled":false}`,
}
numNodes = uint32(5)
subnetParticipants = []string{"node1", "node2", "node3"}
networkParticipants = []string{"node1", "node2", "node3"}
newParticipantNode = "new_participant_node"
subnetParticipants2 = []string{"node1", "node2", newParticipantNode}
networkParticipants2 = []string{"node1", "node2", newParticipantNode}
existingNodes = []string{"node1", "node2", "node3", "node4", "node5"}
disjointNewSubnetParticipants = [][]string{
disjointNewNetworkParticipants = [][]string{
{"new_node1", "new_node2"},
{"new_node3", "new_node4"},
}
@@ -209,7 +209,7 @@ var _ = ginkgo.AfterSuite(func() {
var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
ginkgo.It("can create blockhains", func() {
existingSubnetID := ""
existingChainID := ""
createdBlockchainID := ""
createdBlockchainID2 := ""
ginkgo.By("start with blockchain specs", func() {
@@ -231,8 +231,8 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
ux.Print(logger, log.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
})
ginkgo.By("can create a blockchain with a new subnet id", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain in a new subnet"))
ginkgo.By("can create a blockchain with a new network id", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain in a new network"))
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
resp, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
@@ -247,7 +247,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(len(resp.ChainIds)).Should(gomega.Equal(1))
})
ginkgo.By("get subnet ID", func() {
ginkgo.By("get network ID", func() {
cctx, ccancel := context.WithTimeout(context.Background(), 15*time.Second)
status, err := cli.Status(cctx)
ccancel()
@@ -255,31 +255,31 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
customChains := status.ClusterInfo.GetCustomChains()
_, ok := customChains[createdBlockchainID]
gomega.Ω(ok).Should(gomega.Equal(true))
existingSubnetID = customChains[createdBlockchainID].SubnetId
gomega.Ω(existingSubnetID).Should(gomega.Not(gomega.BeNil()))
existingNetworkID = customChains[createdBlockchainID].PchainId
gomega.Ω(existingNetworkID).Should(gomega.Not(gomega.BeNil()))
})
ginkgo.By("verify the subnet also has all existing nodes as participants", func() {
ginkgo.By("verify the network also has all existing nodes as participants", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
status, err := cli.Status(ctx)
gomega.Ω(err).Should(gomega.BeNil())
subnetIDs := slices.Collect(maps.Keys(status.ClusterInfo.Subnets))
sort.Strings(subnetIDs)
createdSubnetIDString := subnetIDs[0]
subnetHasCorrectParticipants := utils.VerifySubnetHasCorrectParticipants(logger, existingNodes, status.ClusterInfo, createdSubnetIDString)
gomega.Ω(subnetHasCorrectParticipants).Should(gomega.Equal(true))
networkIDs := slices.Collect(maps.Keys(status.ClusterInfo.Chains))
sort.Strings(networkIDs)
createdNetworkIDString := networkIDs[0]
networkHasCorrectParticipants := utils.VerifyNetworkHasCorrectParticipants(logger, existingNodes, status.ClusterInfo, createdNetworkIDString)
gomega.Ω(networkHasCorrectParticipants).Should(gomega.Equal(true))
})
ginkgo.By("can create a blockchain with an existing subnet id", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain in an existing subnet"))
ginkgo.By("can create a blockchain with an existing network id", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain in an existing network"))
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
resp, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
{
VmName: "evm",
Genesis: genesisContents,
SubnetId: &existingSubnetID,
ChainId: &existingNetworkID,
},
},
)
@@ -311,15 +311,15 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(err).Should(gomega.BeNil())
})
ginkgo.By("can create a blockchain with an existing subnet id loaded from snapshot", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain in an existing subnet"))
ginkgo.By("can create a blockchain with an existing network id loaded from snapshot", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain in an existing network"))
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
_, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
{
VmName: "evm",
Genesis: genesisContents,
SubnetId: &existingSubnetID,
ChainId: &existingNetworkID,
},
},
)
@@ -327,15 +327,15 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(err).Should(gomega.BeNil())
})
ginkgo.By("can create a blockchain with new subnet id with some of existing participating nodes", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain with new subnet id with some of existing participating nodes"))
ginkgo.By("can create a blockchain with new network id with some of existing participating nodes", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain with new network id with some of existing participating nodes"))
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
resp, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
{
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: subnetParticipants},
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: networkParticipants},
},
},
)
@@ -345,29 +345,29 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
createdBlockchainID = resp.ChainIds[0]
})
ginkgo.By("verify subnet has correct participants", func() {
ginkgo.By("verify network has correct participants", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
status, err := cli.Status(ctx)
gomega.Ω(err).Should(gomega.BeNil())
customChains := status.ClusterInfo.GetCustomChains()
createdSubnetIDString := customChains[createdBlockchainID].SubnetId
subnetHasCorrectParticipants := utils.VerifySubnetHasCorrectParticipants(logger, subnetParticipants, status.ClusterInfo, createdSubnetIDString)
gomega.Ω(subnetHasCorrectParticipants).Should(gomega.Equal(true))
createdNetworkIDString := customChains[createdBlockchainID].PchainId
networkHasCorrectParticipants := utils.VerifyNetworkHasCorrectParticipants(logger, networkParticipants, status.ClusterInfo, createdNetworkIDString)
gomega.Ω(networkHasCorrectParticipants).Should(gomega.Equal(true))
// verify that no new nodes is added to cluster
gomega.Ω(len(status.ClusterInfo.NodeNames)).Should(gomega.Equal(5))
})
ginkgo.By("can create a blockchain with new subnet id with some of existing participating nodes and a new node", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain new subnet id with some of existing participating nodes and a new node"))
ginkgo.By("can create a blockchain with new network id with some of existing participating nodes and a new node", func() {
ux.Print(logger, log.Blue.Wrap("can create a blockchain with new network id with some of existing participating nodes and a new node"))
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
resp, err := cli.CreateChains(ctx,
[]*rpcpb.BlockchainSpec{
{
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: subnetParticipants2},
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: networkParticipants2},
},
},
)
@@ -381,15 +381,15 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
createdBlockchainID = resp.ChainIds[0]
})
ginkgo.By("verify the newer subnet also has correct participants", func() {
ginkgo.By("verify the newer network also has correct participants", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
status, err := cli.Status(ctx)
gomega.Ω(err).Should(gomega.BeNil())
customChains := status.ClusterInfo.GetCustomChains()
createdSubnetIDString := customChains[createdBlockchainID].SubnetId
subnetHasCorrectParticipants := utils.VerifySubnetHasCorrectParticipants(log, subnetParticipants2, status.ClusterInfo, createdSubnetIDString)
gomega.Ω(subnetHasCorrectParticipants).Should(gomega.Equal(true))
createdNetworkIDString := customChains[createdBlockchainID].PchainId
networkHasCorrectParticipants := utils.VerifyNetworkHasCorrectParticipants(log, networkParticipants2, status.ClusterInfo, createdNetworkIDString)
gomega.Ω(networkHasCorrectParticipants).Should(gomega.Equal(true))
})
ginkgo.By("can create two blockchains at a time", func() {
@@ -399,12 +399,12 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
{
VmName: "evm",
Genesis: genesisContents,
SubnetId: &existingSubnetID,
ChainId: &existingNetworkID,
},
{
VmName: "evm",
Genesis: genesisContents,
SubnetId: &existingSubnetID,
ChainId: &existingNetworkID,
},
},
)
@@ -413,7 +413,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(len(resp.ChainIds)).Should(gomega.Equal(2))
})
ginkgo.By("can create two blockchains in two new disjoint subnets with bls validators", func() {
ginkgo.By("can create two blockchains in two new disjoint networks with bls validators", func() {
// get prev status
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
prevStatus, err := cli.Status(ctx)
@@ -426,19 +426,19 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
{
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewSubnetParticipants[0]},
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewNetworkParticipants[0]},
},
{
VmName: "evm",
Genesis: genesisContents,
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewSubnetParticipants[1]},
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewNetworkParticipants[1]},
},
},
)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
// check new nodes
allNewParticipants := append(disjointNewSubnetParticipants[0], disjointNewSubnetParticipants[1]...)
allNewParticipants := append(disjointNewNetworkParticipants[0], disjointNewNetworkParticipants[1]...)
expectedLen := len(prevStatus.ClusterInfo.NodeNames) + len(allNewParticipants)
gomega.Ω(len(resp.ClusterInfo.NodeNames)).Should(gomega.Equal(expectedLen))
for _, nodeName := range allNewParticipants {
@@ -450,18 +450,18 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
createdBlockchainID2 = resp.ChainIds[1]
})
ginkgo.By("verify the new subnets also has correct participants", func() {
ginkgo.By("verify the new networks also has correct participants", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
status, err := cli.Status(ctx)
gomega.Ω(err).Should(gomega.BeNil())
customChains := status.ClusterInfo.GetCustomChains()
createdSubnetIDString := customChains[createdBlockchainID].SubnetId
subnetHasCorrectParticipants := utils.VerifySubnetHasCorrectParticipants(log, disjointNewSubnetParticipants[0], status.ClusterInfo, createdSubnetIDString)
gomega.Ω(subnetHasCorrectParticipants).Should(gomega.Equal(true))
createdSubnetID2String := customChains[createdBlockchainID2].SubnetId
subnet2HasCorrectParticipants := utils.VerifySubnetHasCorrectParticipants(log, disjointNewSubnetParticipants[1], status.ClusterInfo, createdSubnetID2String)
gomega.Ω(subnet2HasCorrectParticipants).Should(gomega.Equal(true))
createdNetworkIDString := customChains[createdBlockchainID].PchainId
networkHasCorrectParticipants := utils.VerifyNetworkHasCorrectParticipants(log, disjointNewNetworkParticipants[0], status.ClusterInfo, createdNetworkIDString)
gomega.Ω(networkHasCorrectParticipants).Should(gomega.Equal(true))
createdNetworkID2String := customChains[createdBlockchainID2].PchainId
network2HasCorrectParticipants := utils.VerifyNetworkHasCorrectParticipants(log, disjointNewNetworkParticipants[1], status.ClusterInfo, createdNetworkID2String)
gomega.Ω(network2HasCorrectParticipants).Should(gomega.Equal(true))
})
ginkgo.By("verify that new validators have BLS Keys", func() {
@@ -478,7 +478,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(err).Should(gomega.BeNil())
status, err := cli.Status(ctx)
gomega.Ω(err).Should(gomega.BeNil())
allNewParticipants := append(disjointNewSubnetParticipants[0], disjointNewSubnetParticipants[1]...)
allNewParticipants := append(disjointNewNetworkParticipants[0], disjointNewNetworkParticipants[1]...)
for _, nodeName := range allNewParticipants {
nodeInfo, ok := status.ClusterInfo.NodeInfos[nodeName]
gomega.Ω(ok).Should(gomega.Equal(true))
@@ -819,12 +819,12 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
cancel()
gomega.Ω(err).Should(gomega.BeNil())
})
ginkgo.By("add 1 subnet", func() {
ginkgo.By("add 1 network", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
resp, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{}})
cancel()
gomega.Ω(err).Should(gomega.BeNil())
gomega.Ω(len(resp.SubnetIds)).Should(gomega.Equal(1))
gomega.Ω(len(resp.ChainIds)).Should(gomega.Equal(1))
})
ginkgo.By("verify that new validator has BLS Keys", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
@@ -849,48 +849,48 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
})
})
ginkgo.It("subnet creation", func() {
ginkgo.By("add 1 subnet", func() {
ginkgo.It("network creation", func() {
ginkgo.By("add 1 network", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
_, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{}})
cancel()
gomega.Ω(err).Should(gomega.BeNil())
})
ginkgo.By("check subnet number is 2", func() {
ginkgo.By("check network number is 2", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
numSubnets := len(status.ClusterInfo.Subnets)
gomega.Ω(numSubnets).Should(gomega.Equal(2))
numNetworks := len(status.ClusterInfo.Chains)
gomega.Ω(numNetworks).Should(gomega.Equal(2))
})
ginkgo.By("add 1 subnet with participants", func() {
ginkgo.By("add 1 network with participants", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
response, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{Participants: subnetParticipants}})
response, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{Participants: networkParticipants}})
cancel()
gomega.Ω(err).Should(gomega.BeNil())
gomega.Ω(len(response.SubnetIds)).Should(gomega.Equal(1))
newSubnetID = response.SubnetIds[0]
gomega.Ω(len(response.ChainIds)).Should(gomega.Equal(1))
newNetworkID = response.ChainIds[0]
})
ginkgo.By("verify subnet has correct participants", func() {
ginkgo.By("verify network has correct participants", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
status, err := cli.Status(ctx)
gomega.Ω(err).Should(gomega.BeNil())
subnetHasCorrectParticipants := utils.VerifySubnetHasCorrectParticipants(log, subnetParticipants, status.ClusterInfo, newSubnetID)
gomega.Ω(subnetHasCorrectParticipants).Should(gomega.Equal(true))
networkHasCorrectParticipants := utils.VerifyNetworkHasCorrectParticipants(log, networkParticipants, status.ClusterInfo, newNetworkID)
gomega.Ω(networkHasCorrectParticipants).Should(gomega.Equal(true))
})
ginkgo.By("add 1 subnet with node not currently added", func() {
ginkgo.By("add 1 network with node not currently added", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
response, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{Participants: subnetParticipants2}})
response, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{Participants: networkParticipants2}})
cancel()
gomega.Ω(err).Should(gomega.BeNil())
// verify that a new node is added to cluster
gomega.Ω(len(response.ClusterInfo.NodeNames)).Should(gomega.Equal(7))
_, ok := response.ClusterInfo.NodeInfos[newParticipantNode]
gomega.Ω(ok).Should(gomega.Equal(true))
gomega.Ω(len(response.SubnetIds)).Should(gomega.Equal(1))
newSubnetID = response.SubnetIds[0]
gomega.Ω(len(response.ChainIds)).Should(gomega.Equal(1))
newNetworkID = response.ChainIds[0]
})
ginkgo.By("calling AddNode with existing node name, should fail", func() {
ux.Print(logger, log.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
@@ -901,28 +901,28 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(resp).Should(gomega.BeNil())
ux.Print(logger, log.Green.Wrap("'add-node' failed as expected"))
})
ginkgo.By("verify the newer subnet also has correct participants", func() {
ginkgo.By("verify the newer network also has correct participants", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
status, err := cli.Status(ctx)
gomega.Ω(err).Should(gomega.BeNil())
subnetHasCorrectParticipants := utils.VerifySubnetHasCorrectParticipants(logger, subnetParticipants2, status.ClusterInfo, newSubnetID)
gomega.Ω(subnetHasCorrectParticipants).Should(gomega.Equal(true))
networkHasCorrectParticipants := utils.VerifyNetworkHasCorrectParticipants(logger, networkParticipants2, status.ClusterInfo, newNetworkID)
gomega.Ω(networkHasCorrectParticipants).Should(gomega.Equal(true))
})
})
ginkgo.It("can remove subnet validator", func() {
ginkgo.By("removing a subnet validator", func() {
ginkgo.It("can remove network validator", func() {
ginkgo.By("removing a network validator", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
testRemoveSubnetValidatorConfig := rpcpb.RemoveChainValidatorSpec{
testRemoveNetworkValidatorConfig := rpcpb.RemoveChainValidatorSpec{
NodeNames: []string{"node2"},
SubnetId: newSubnetID,
ChainId: newNetworkID,
}
_, err := cli.RemoveSubnetValidator(ctx, []*rpcpb.RemoveChainValidatorSpec{&testRemoveSubnetValidatorConfig})
_, err := cli.RemoveChainValidator(ctx, []*rpcpb.RemoveChainValidatorSpec{&testRemoveNetworkValidatorConfig})
gomega.Ω(err).Should(gomega.BeNil())
})
ginkgo.By("verify there are only two validators left for subnet", func() {
ginkgo.By("verify there are only two validators left for network", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
clientURIs, err := cli.URIs(ctx)
@@ -932,40 +932,40 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
clientURI = uri
break
}
subnetID, err := ids.FromString(newSubnetID)
networkID, err := ids.FromString(newNetworkID)
gomega.Ω(err).Should(gomega.BeNil())
platformCli := platformvm.NewClient(clientURI)
vdrs, err := platformCli.GetCurrentValidators(ctx, subnetID, nil)
vdrs, err := platformCli.GetCurrentValidators(ctx, networkID, nil)
gomega.Ω(err).Should(gomega.BeNil())
gomega.Ω(len(vdrs)).Should(gomega.Equal(2))
})
})
ginkgo.It("transform subnet to elastic subnets", func() {
var elasticSubnetID string
ginkgo.By("add 1 subnet", func() {
ginkgo.It("transform network to elastic networks", func() {
var elasticNetworkID string
ginkgo.By("add 1 network", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
resp, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{}})
cancel()
gomega.Ω(err).Should(gomega.BeNil())
gomega.Ω(len(resp.SubnetIds)).Should(gomega.Equal(1))
gomega.Ω(len(resp.ClusterInfo.Subnets)).Should(gomega.Equal(5))
createdSubnetID = resp.SubnetIds[0]
gomega.Ω(len(resp.ChainIds)).Should(gomega.Equal(1))
gomega.Ω(len(resp.ClusterInfo.Chains)).Should(gomega.Equal(5))
createdNetworkID = resp.ChainIds[0]
})
ginkgo.By("check expected non elastic status", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
subnetInfo := status.ClusterInfo.Subnets[createdSubnetID]
gomega.Ω(subnetInfo.IsElastic).Should(gomega.Equal(false))
gomega.Ω(subnetInfo.ElasticChainId).Should(gomega.Equal(ids.Empty.String()))
networkInfo := status.ClusterInfo.Chains[createdNetworkID]
gomega.Ω(networkInfo.IsElastic).Should(gomega.Equal(false))
gomega.Ω(networkInfo.ElasticChainId).Should(gomega.Equal(ids.Empty.String()))
})
ginkgo.By("transform 1 subnet to elastic subnet", func() {
ginkgo.By("transform 1 network to elastic network", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
testElasticSubnetConfig.SubnetId = createdSubnetID
response, err := cli.TransformElasticSubnets(ctx, []*rpcpb.ElasticParticipantsSpec{&testElasticSubnetConfig})
testElasticChainConfig.ChainId = createdNetworkID
response, err := cli.TransformElasticChains(ctx, []*rpcpb.ElasticChainSpec{&testElasticChainConfig})
gomega.Ω(err).Should(gomega.BeNil())
gomega.Ω(len(response.TxIds)).Should(gomega.Equal(1))
gomega.Ω(len(response.AssetIds)).Should(gomega.Equal(1))
@@ -976,16 +976,16 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
subnetInfo := status.ClusterInfo.Subnets[createdSubnetID]
gomega.Ω(subnetInfo.IsElastic).Should(gomega.Equal(true))
gomega.Ω(subnetInfo.ElasticChainId).ShouldNot(gomega.Equal(ids.Empty.String()))
elasticSubnetID = subnetInfo.ElasticChainId
networkInfo := status.ClusterInfo.Chains[createdNetworkID]
gomega.Ω(networkInfo.IsElastic).Should(gomega.Equal(true))
gomega.Ω(networkInfo.ElasticChainId).ShouldNot(gomega.Equal(ids.Empty.String()))
elasticNetworkID = networkInfo.ElasticChainId
})
ginkgo.By("transforming a subnet with same subnetID to elastic subnet will fail", func() {
ginkgo.By("transforming a network with same networkID to elastic network will fail", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
testElasticSubnetConfig.SubnetId = createdSubnetID
_, err := cli.TransformElasticSubnets(ctx, []*rpcpb.ElasticParticipantsSpec{&testElasticSubnetConfig})
testElasticChainConfig.ChainId = createdNetworkID
_, err := cli.TransformElasticChains(ctx, []*rpcpb.ElasticChainSpec{&testElasticChainConfig})
gomega.Ω(err).Should(gomega.HaveOccurred())
})
ginkgo.By("save snapshot with elastic info", func() {
@@ -1005,9 +1005,9 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
subnetInfo := status.ClusterInfo.Subnets[createdSubnetID]
gomega.Ω(subnetInfo.IsElastic).Should(gomega.Equal(true))
gomega.Ω(subnetInfo.ElasticChainId).Should(gomega.Equal(elasticSubnetID))
networkInfo := status.ClusterInfo.Chains[createdNetworkID]
gomega.Ω(networkInfo.IsElastic).Should(gomega.Equal(true))
gomega.Ω(networkInfo.ElasticChainId).Should(gomega.Equal(elasticNetworkID))
})
ginkgo.By("remove snapshot with elastic info", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
@@ -1017,11 +1017,11 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
})
})
ginkgo.It("add permissionless validator to elastic subnets", func() {
ginkgo.By("adding a permissionless validator to elastic subnet", func() {
ginkgo.It("add permissionless validator to elastic networks", func() {
ginkgo.By("adding a permissionless validator to elastic network", func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
testValidatorConfig.SubnetId = createdSubnetID
testValidatorConfig.ChainId = createdNetworkID
testValidatorConfig.AssetId = elasticAssetID
testValidatorConfig.NodeName = "permissionlessNode"
_, err := cli.AddPermissionlessValidator(ctx, []*rpcpb.PermissionlessValidatorSpec{&testValidatorConfig})
@@ -1031,7 +1031,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
ginkgo.It("snapshots + blockchain creation", func() {
var originalUris []string
var originalSubnets []string
var originalNetworks []string
ginkgo.By("get original URIs", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
var err error
@@ -1040,14 +1040,14 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(err).Should(gomega.BeNil())
gomega.Ω(len(originalUris)).Should(gomega.Equal(8))
})
ginkgo.By("get original subnets", func() {
ginkgo.By("get original networks", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
numSubnets := len(status.ClusterInfo.Subnets)
gomega.Ω(numSubnets).Should(gomega.Equal(5))
originalSubnets = slices.Collect(maps.Keys(status.ClusterInfo.Subnets))
numNetworks := len(status.ClusterInfo.Chains)
gomega.Ω(numNetworks).Should(gomega.Equal(5))
originalNetworks = slices.Collect(maps.Keys(status.ClusterInfo.Chains))
})
ginkgo.By("check there are no snapshots", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
@@ -1088,15 +1088,15 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
gomega.Ω(err).Should(gomega.BeNil())
gomega.Ω(uris).Should(gomega.Equal(originalUris))
})
ginkgo.By("check subnets", func() {
ginkgo.By("check networks", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
subnetIDs := slices.Collect(maps.Keys(status.ClusterInfo.Subnets))
sort.Strings(subnetIDs)
sort.Strings(originalSubnets)
gomega.Ω(subnetIDs).Should(gomega.Equal(originalSubnets))
networkIDs := slices.Collect(maps.Keys(status.ClusterInfo.Chains))
sort.Strings(networkIDs)
sort.Strings(originalNetworks)
gomega.Ω(networkIDs).Should(gomega.Equal(originalNetworks))
})
ginkgo.By("save fail for already saved snapshot", func() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
+1 -1
View File
@@ -11,7 +11,7 @@
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"subnetEVMTimestamp": 0,
"luxEvmTimestamp": 0,
"feeConfig": {
"gasLimit": 20000000,
"minBaseFee": 1000000000,
+3 -3
View File
@@ -5,8 +5,6 @@ import (
"os/exec"
"strings"
"testing"
"github.com/luxfi/log"
)
// TestColorAssignment tests that each color assignment is different and that it "wraps"
@@ -84,7 +82,9 @@ func TestColorAndPrepend(t *testing.T) {
}
// 4 is []<space>\n
expLen := len("test") + len(color) + len(fakeNodeName) + 4 + len(log.Reset)
// color.Wrap("") returns the color escape + reset escape sequences
colorOverhead := len(color.Wrap(""))
expLen := len("test") + colorOverhead + len(fakeNodeName) + 4
if len(res) != expLen {
t.Fatalf("expected lengh to be %d, but was %d", expLen, len(res))
}
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"time"
"github.com/luxfi/ids"
"github.com/luxfi/log"
log "github.com/luxfi/log"
rpcb "github.com/luxfi/netrunner/rpcpb"
"github.com/luxfi/netrunner/ux"
luxtls "github.com/luxfi/tls"
+1 -1
View File
@@ -5,7 +5,7 @@ package ux
import (
"fmt"
"github.com/luxfi/log"
log "github.com/luxfi/log"
)
//nolint:govet // msg is intentionally a format string that may come from variables