scrub: subnet/l2 → chain (canonical vocabulary, forward-only)

Wire-format codec IDs unchanged. CLI aliases deleted; chain is the
command. No backwards-compat shims, no deprecation comments.
This commit is contained in:
Hanzo AI
2026-05-31 15:09:15 -07:00
parent 89888e6247
commit 43ead226a9
12 changed files with 79 additions and 1450 deletions
+2 -2
View File
@@ -6,7 +6,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, chains (L2 blockchains), 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, application chains, and complex network topologies.
## Essential Commands
@@ -1091,7 +1091,7 @@ After fixes, successfully deployed Zoo chain on mainnet:
### RLP Block Import Limitation
**Discovery**: The L2 EVM doesn't support `admin_importChain` RPC method. Blocks in L2 EVM chains come through Lux consensus, not direct import.
**Discovery**: The EVM plugin doesn't support `admin_importChain` RPC method. Blocks in EVM chains come through Lux consensus, not direct import.
**Available RPC modules on Zoo chain**: eth, net, rpc, web3 (no admin or debug)
+43 -43
View File
@@ -137,7 +137,7 @@ Additional optional parameters which can be passed to the start command:
```bash
--plugin-dir ${LUXD_PLUGIN_PATH} \
--blockchain-specs '[{"vm_name": "subnetevm", "genesis": "/tmp/subnet-evm.genesis.json"}]'
--blockchain-specs '[{"vm_name": "evm", "genesis": "/tmp/evm.genesis.json"}]'
--global-node-config '{"index-enabled":false, "api-admin-enabled":true,"network-peer-list-gossip-frequency":"300ms"}'
--custom-node-configs" '{"node1":{"log-level":"debug","api-admin-enabled":false},"node2":{...},...}'
```
@@ -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 chain (L2 blockchain) operation.
See the [chain deployment](#network-runner-rpc-server-l2-evm-example) section for details about how to run chains.
`--plugin-dir` and `--blockchain-specs` are parameters relevant to chain operation.
See the [chain deployment](#network-runner-rpc-server-evm-example) section for details about how to run chains.
The network-runner supports node node configuration at different levels.
@@ -302,38 +302,38 @@ netrunner control remove-snapshot snapshotName
To create 1 chain (validator set), with all existing nodes as participants (requires network restart):
```bash
curl -X POST -k http://localhost:8081/v1/control/createsubnets -d '[{}]'
curl -X POST -k http://localhost:8081/v1/control/createchains -d '[{}]'
# or
netrunner control create-subnets '[{}]'
netrunner control create-chains '[{}]'
```
To create 1 chain (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"]}]'
curl -X POST -k http://localhost:8081/v1/control/createchains -d '[{"participants": ["node1", "node2"]}]'
# or
netrunner control create-subnets '[{"participants": ["node1", "node2"]}]'
netrunner control create-chains '[{"participants": ["node1", "node2"]}]'
```
To create 1 chain (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"]}]'
curl -X POST -k http://localhost:8081/v1/control/createchains -d '[{"participants": ["node1", "node2", "testNode"]}]'
# or
netrunner control create-subnets '[{"participants": ["node1", "node2", "testNode"]}]'
netrunner control create-chains '[{"participants": ["node1", "node2", "testNode"]}]'
```
To create N chains (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"]}]'
curl -X POST -k http://localhost:8081/v1/control/createchains -d '[{}, {"participants": ["node1", "node2", "node3"]}, {"participants": ["node1", "node2", "testNode"]}]'
# or
netrunner control create-subnets '[{}, {"participants": ["node1", "node2", "node3"]}, {"participants": ["node1", "node2", "testNode"]}]'
netrunner control create-chains '[{}, {"participants": ["node1", "node2", "node3"]}, {"participants": ["node1", "node2", "testNode"]}]'
```
@@ -358,38 +358,38 @@ netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENE
To create a blockchain with a chain 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'"}]}'
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "blockchain_id": "'$BLOCKCHAIN_ID'"}]}'
# or
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_id": "'$SUBNET_ID'"}]' --plugin-dir $PLUGIN_DIR
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "blockchain_id": "'$BLOCKCHAIN_ID'"}]' --plugin-dir $PLUGIN_DIR
```
To create a blockchain with a chain ID, and chain config, network upgrade and chain 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'"}]}'
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "blockchain_id": "'$BLOCKCHAIN_ID'", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "chain_config_per_chain": "'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]}'
# or
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
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "blockchain_id": "'$BLOCKCHAIN_ID'", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "chain_config_per_chain": "'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]' --plugin-dir $PLUGIN_DIR
```
To create a blockchain with a new chain with select nodes as participants (requires network restart):
(New nodes will first be added as primary validators similar to the process in `create-subnets`)
(New nodes will first be added as primary validators similar to the process in `create-chains`)
```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": ["node1", "node2", "testNode"]}"]}'
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "chain_spec": "{"participants": ["node1", "node2", "testNode"]}"]}'
# or
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_spec": "{"participants": ["node1", "node2", "testNode"]}]' --plugin-dir $PLUGIN_DIR
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "chain_spec": "{"participants": ["node1", "node2", "testNode"]}]' --plugin-dir $PLUGIN_DIR
```
To create two blockchains in two disjoint chains (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"]}}]'
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "chain_spec": {"participants": ["new_node1", "new_node2"]}},{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "chain_spec": {"participants": ["new_node3", "new_node4"]}}]'
# or
go run main.go control create-blockchains '[{"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"]}}]'
go run main.go control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "chain_spec": {"participants": ["new_node1", "new_node2"]}},{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "chain_spec": {"participants": ["new_node3", "new_node4"]}}]'
```
Chain config can also be defined on a per node basis. For that, a per node chain config file is needed, which is a JSON that specifies the chain config per node. For example, given the following as the contents of the file with path `$PER_NODE_CHAIN_CONFIG`:
@@ -407,10 +407,10 @@ Chain config can also be defined on a per node basis. For that, a per node chain
Then a blockchain with different chain configs per node can be created with this command:
```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'", "per_node_chain_config": "'$PER_NODE_CHAIN_CONFIG'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "subnet_config": "'$SUBNET_CONFIG_PATH'"}]}'
curl -X POST -k http://localhost:8081/v1/control/createblockchains -d '{"pluginDir":"'$PLUGIN_DIR'","blockchainSpecs":[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "blockchain_id": "'$BLOCKCHAIN_ID'", "per_node_chain_config": "'$PER_NODE_CHAIN_CONFIG'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "chain_config_per_chain": "'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]}'
# or
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "subnet_id": "'$SUBNET_ID'", "per_node_chain_config": "'$PER_NODE_CHAIN_CONFIG'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "subnet_config": "'$SUBNET_CONFIG_PATH'"}]' --plugin-dir $PLUGIN_DIR
netrunner control create-blockchains '[{"vm_name":"'$VM_NAME'","genesis":"'$GENESIS_PATH'", "blockchain_id": "'$BLOCKCHAIN_ID'", "per_node_chain_config": "'$PER_NODE_CHAIN_CONFIG'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "chain_config_per_chain": "'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]' --plugin-dir $PLUGIN_DIR
```
To remove (stop) a node:
@@ -552,7 +552,7 @@ netrunner control stop \
--endpoint="0.0.0.0:8080"
```
## `network-runner` RPC server: L2 EVM example
## `network-runner` RPC server: EVM chain example
To start the server:
@@ -569,10 +569,10 @@ curl -X POST -k http://localhost:8081/v1/ping -d ''
To start the cluster with custom chains:
```bash
# or download from https://github.com/luxfi/subnet-cli/releases
cd ${HOME}/go/src/github.com/luxfi/subnet-cli
# or download from https://github.com/luxfi/cli/releases
cd ${HOME}/go/src/github.com/luxfi/cli
go install -v .
subnet-cli create VMID subnetevm
lux chain create VMID evm
# srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy
# download from https://github.com/luxfi/sdk/node/releases
@@ -581,8 +581,8 @@ rm -rf ${HOME}/go/src/github.com/luxfi/sdk/node/build
cd ${HOME}/go/src/github.com/luxfi/node
./scripts/build.sh
# ref. https://github.com/luxfi/subnet-evm/blob/b69e47e0398b5237cda0422f6a32969e64bde346/scripts/run.sh
cd ${HOME}/go/src/github.com/luxfi/subnet-evm
# ref. https://github.com/luxfi/evm/blob/b69e47e0398b5237cda0422f6a32969e64bde346/scripts/run.sh
cd ${HOME}/go/src/github.com/luxfi/evm
go build -v \
-o ${HOME}/go/src/github.com/luxfi/sdk/node/build/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy \
./plugin
@@ -599,7 +599,7 @@ find ${HOME}/go/src/github.com/luxfi/sdk/node/build
# generate the genesis for the custom chain
export CHAIN_ID=99999
export GENESIS_ADDRESS="0x9011E888251AB053B7bD1cdB598Db4f9DEd94714"
cat <<EOF > /tmp/subnet-evm.genesis.json
cat <<EOF > /tmp/evm.genesis.json
{
"config": {
"chainId": $CHAIN_ID,
@@ -642,7 +642,7 @@ cat <<EOF > /tmp/subnet-evm.genesis.json
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
EOF
cat /tmp/subnet-evm.genesis.json
cat /tmp/evm.genesis.json
```
```bash
@@ -650,7 +650,7 @@ cat /tmp/subnet-evm.genesis.json
LUXD_EXEC_PATH="${HOME}/go/src/github.com/luxfi/sdk/node/build/node"
LUXD_PLUGIN_PATH="${HOME}/go/src/github.com/luxfi/sdk/node/build/plugins"
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"}]}'
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":"evm","genesis":"/tmp/evm.genesis.json"}]}'
# or
netrunner control start \
@@ -658,7 +658,7 @@ netrunner control start \
--endpoint="0.0.0.0:8080" \
--node-path ${LUXD_EXEC_PATH} \
--plugin-dir ${LUXD_PLUGIN_PATH} \
--blockchain-specs '[{"vm_name": "subnetevm", "genesis": "/tmp/subnet-evm.genesis.json"}]'
--blockchain-specs '[{"vm_name": "evm", "genesis": "/tmp/evm.genesis.json"}]'
```
```bash
@@ -669,7 +669,7 @@ curl -X POST -k http://localhost:8081/v1/control/status -d ''
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'"}]}'
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":"evm","genesis":"/tmp/evm.genesis.json","chain_config":"'$CHAIN_CONFIG_PATH'","network_upgrade":"'$NETWORK_UPGRADE_PATH'","chain_config_per_chain":"'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]}'
# or
netrunner control start \
@@ -677,7 +677,7 @@ netrunner control start \
--endpoint="0.0.0.0:8080" \
--node-path ${LUXD_EXEC_PATH} \
--plugin-dir ${LUXD_PLUGIN_PATH} \
--blockchain-specs '[{"vm_name": "subnetevm", "genesis": "/tmp/subnet-evm.genesis.json", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "subnet_config": "'$SUBNET_CONFIG_PATH'"}]'
--blockchain-specs '[{"vm_name": "evm", "genesis": "/tmp/evm.genesis.json", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "chain_config_per_chain": "'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]'
```
## `network-runner` RPC server: `blobvm` example
@@ -697,10 +697,10 @@ curl -X POST -k http://localhost:8081/v1/ping -d ''
To start the cluster with custom chains:
```bash
# or download from https://github.com/luxfi/subnet-cli/releases
cd ${HOME}/go/src/github.com/luxfi/subnet-cli
# or download from https://github.com/luxfi/cli/releases
cd ${HOME}/go/src/github.com/luxfi/cli
go install -v .
subnet-cli create VMID blobvm
lux chain create VMID blobvm
# kM6h4LYe3AcEU1MB2UNg6ubzAiDAALZzpVrbX8zn3hXF6Avd8
# download from https://github.com/luxfi/sdk/node/releases
@@ -755,7 +755,7 @@ curl -X POST -k http://localhost:8081/v1/control/status -d ''
Blockchain config file and network upgrade 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":"blobvm","genesis":"/tmp/blobvm.json","chain_config":"'$CHAIN_CONFIG_PATH'","network_upgrade":"'$NETWORK_UPGRADE_PATH'","subnet_config":"'$SUBNET_CONFIG_PATH'"}]}'
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":"blobvm","genesis":"/tmp/blobvm.json","chain_config":"'$CHAIN_CONFIG_PATH'","network_upgrade":"'$NETWORK_UPGRADE_PATH'","chain_config_per_chain":"'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]}'
# or
netrunner control start \
@@ -763,7 +763,7 @@ netrunner control start \
--endpoint="0.0.0.0:8080" \
--node-path ${LUXD_EXEC_PATH} \
--plugin-dir ${LUXD_PLUGIN_PATH} \
--blockchain-specs '[{"vm_name": "blobvm", "genesis": "/tmp/blobvm.genesis.json", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "subnet_config": "'$SUBNET_CONFIG_PATH'"}]'
--blockchain-specs '[{"vm_name": "blobvm", "genesis": "/tmp/blobvm.genesis.json", "chain_config": "'$CHAIN_CONFIG_PATH'", "network_upgrade": "'$NETWORK_UPGRADE_PATH'", "chain_config_per_chain": "'$CHAIN_CONFIG_PER_CHAIN_PATH'"}]'
```
## `network-runner` RPC server: `timestampvm` example
@@ -783,10 +783,10 @@ curl -X POST -k http://localhost:8081/v1/ping -d ''
To start the cluster with custom chains:
```bash
# or download from https://github.com/luxfi/subnet-cli/releases
cd ${HOME}/go/src/github.com/luxfi/subnet-cli
# or download from https://github.com/luxfi/cli/releases
cd ${HOME}/go/src/github.com/luxfi/cli
go install -v .
subnet-cli create VMID timestampvm
lux chain create VMID timestampvm
# tGas3T58KzdjcJ2iKSyiYsWiqYctRXaPTqBCA11BqEkNg8kPc
# download from https://github.com/luxfi/sdk/node/releases
@@ -904,7 +904,7 @@ type Config struct {
// May be nil.
UpgradeConfigFiles map[string]string `json:"upgradeConfigFiles"`
// May be nil.
SubnetConfigFiles map[string]string `json:"subnetConfigFiles"`
ChainConfigPerChainFiles map[string]string `json:"chainConfigPerChainFiles"`
// Flags can hold additional flags for the node.
// It can be empty.
// The precedence of flags handling is:
+1 -1
View File
@@ -5,7 +5,7 @@ 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, chains (L2 blockchains), 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, application chains, and complex network topologies.
## Overview
+8 -8
View File
@@ -194,26 +194,26 @@ cat > elastic-network.json <<EOF
EOF
# Create elastic network
netrunner control create-elastic-subnet elastic-network.json
netrunner control create-elastic-chain elastic-network.json
```
## Custom Blockchain Deployment
### Deploy Subnet-EVM
### Deploy EVM Chain
```bash
# Generate VM ID
subnet-cli create VMID subnetevm
lux chain create VMID evm
# Output: srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy
# Build the plugin
cd ${HOME}/go/src/github.com/luxfi/subnet-evm
cd ${HOME}/go/src/github.com/luxfi/evm
go build -v \
-o ${LUXD_PLUGIN_PATH}/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy \
./plugin
# Create genesis
cat > /tmp/subnet-evm.genesis.json <<EOF
cat > /tmp/evm.genesis.json <<EOF
{
"config": {
"chainId": 99999,
@@ -250,15 +250,15 @@ cat > /tmp/subnet-evm.genesis.json <<EOF
}
EOF
# Start network with subnet-evm
# Start network with EVM
netrunner control start \
--endpoint="0.0.0.0:8080" \
--number-of-nodes=3 \
--node-path ${LUXD_EXEC_PATH} \
--plugin-dir ${LUXD_PLUGIN_PATH} \
--blockchain-specs '[{
"vm_name": "subnetevm",
"genesis": "/tmp/subnet-evm.genesis.json"
"vm_name": "evm",
"genesis": "/tmp/evm.genesis.json"
}]'
```
+4 -4
View File
@@ -59,10 +59,10 @@ engines:
- eth2-settlement
wait_healthy: true
# ZOO L2 Chain on Lux
# ZOO Chain on Lux
- name: zoo-chain
type: lux
binary: "subnet-evm"
binary: "evm"
network_id: 200200
http_port: 9640
ws_port: 9641
@@ -74,10 +74,10 @@ engines:
- lux-mainnet
wait_healthy: true
# SPC L2 Chain on Lux
# SPC Chain on Lux
- name: spc-chain
type: lux
binary: "subnet-evm"
binary: "evm"
network_id: 36911
http_port: 9642
ws_port: 9643
Executable
BIN
View File
Binary file not shown.
-18
View File
@@ -5,24 +5,6 @@
"new_name": "plugin-dir",
"value_map": "parent-dir"
},
{
"version": "v1.9.6",
"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": "chain-config-dir",
"value_map": ""
},
{
"version": "v1.22.0",
"old_name": "net-config-dir",
+1 -1
View File
@@ -19,7 +19,7 @@ type NetworkType string
const (
NetworkTypePrimary NetworkType = "primary" // Mainnet or Testnet
NetworkTypeChain NetworkType = "chain" // L1/L2 chains
NetworkTypeChain NetworkType = "chain" // Application chains
)
// NetworkConfig defines configuration for a single network
-225
View File
@@ -1,225 +0,0 @@
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package orchestrator_test
import (
"context"
"testing"
"time"
"github.com/luxfi/netrunner/engines"
"github.com/luxfi/netrunner/orchestrator"
"github.com/stretchr/testify/require"
)
func TestMultiEngineOrchestration(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
ctx := context.Background()
host := orchestrator.NewHost()
// Test starting Lux engine
t.Run("StartLuxEngine", func(t *testing.T) {
config := &engines.NodeConfig{
NetworkID: 96369,
HTTPPort: 19630,
StakingPort: 19631,
LogLevel: "info",
Extra: map[string]interface{}{
"staking-enabled": false,
"sybil-protection-enabled": false,
"health-check-frequency": "2s",
},
}
err := host.StartEngine(ctx, "test-lux", engines.EngineLux, config)
require.NoError(t, err)
// Wait for health
time.Sleep(5 * time.Second)
// Check engine is listed
engines := host.ListEngines()
require.Len(t, engines, 1)
require.Equal(t, "test-lux", engines[0].Name)
require.Equal(t, "lux", engines[0].Type)
// Stop engine
err = host.StopEngine(ctx, "test-lux")
require.NoError(t, err)
})
// Test starting multiple engines
t.Run("MultipleEngines", func(t *testing.T) {
// Start Lux
luxConfig := &engines.NodeConfig{
NetworkID: 96369,
HTTPPort: 19630,
StakingPort: 19631,
LogLevel: "info",
}
err := host.StartEngine(ctx, "lux-1", engines.EngineLux, luxConfig)
require.NoError(t, err)
// Start Lux
avaConfig := &engines.NodeConfig{
NetworkID: 43114,
HTTPPort: 19640,
StakingPort: 19641,
LogLevel: "info",
}
err = host.StartEngine(ctx, "ava-1", engines.EngineLux, avaConfig)
require.NoError(t, err)
// Check both are running
engines := host.ListEngines()
require.Len(t, engines, 2)
// Clean up
host.StopEngine(ctx, "lux-1")
host.StopEngine(ctx, "ava-1")
})
}
func TestStackManifest(t *testing.T) {
manifest := &orchestrator.StackManifest{
Name: "test-stack",
Version: "1.0.0",
Description: "Test stack",
Engines: []orchestrator.EngineConfig{
{
Name: "lux-l1",
Type: "lux",
NetworkID: 96369,
HTTPPort: 9630,
StakingPort: 9631,
WaitHealthy: true,
},
{
Name: "lux-l2",
Type: "op",
NetworkID: 200200,
HTTPPort: 8545,
DependsOn: []string{"lux-l1"},
},
},
}
t.Run("Validate", func(t *testing.T) {
err := manifest.Validate()
require.NoError(t, err)
})
t.Run("SaveAndLoad", func(t *testing.T) {
// Save as YAML
yamlPath := "/tmp/test-stack.yaml"
err := manifest.Save(yamlPath)
require.NoError(t, err)
// Load back
loaded, err := orchestrator.LoadManifest(yamlPath)
require.NoError(t, err)
require.Equal(t, manifest.Name, loaded.Name)
require.Len(t, loaded.Engines, 2)
// Save as JSON
jsonPath := "/tmp/test-stack.json"
err = manifest.Save(jsonPath)
require.NoError(t, err)
// Load JSON
loaded, err = orchestrator.LoadManifest(jsonPath)
require.NoError(t, err)
require.Equal(t, manifest.Name, loaded.Name)
})
}
func TestPortManager(t *testing.T) {
pm := orchestrator.NewPortManager()
t.Run("AllocatePorts", func(t *testing.T) {
// Allocate HTTP ports
port1 := pm.AllocateHTTP()
port2 := pm.AllocateHTTP()
require.NotEqual(t, port1, port2)
// Allocate P2P ports
p2p1 := pm.AllocateP2P()
p2p2 := pm.AllocateP2P()
require.NotEqual(t, p2p1, p2p2)
// Release and reallocate
pm.Release(port1)
port3 := pm.AllocateHTTP()
// May or may not reuse port1 depending on system state
require.NotEqual(t, port3, port2)
})
t.Run("ReservePorts", func(t *testing.T) {
pm := orchestrator.NewPortManager()
// Reserve specific ports
err := pm.Reserve(20000, 20001, 20002)
require.NoError(t, err)
// Try to reserve again - should fail
err = pm.Reserve(20001)
require.Error(t, err)
})
}
func TestMetricsCollector(t *testing.T) {
mc := orchestrator.NewMetricsCollector()
t.Run("RecordAndRetrieve", func(t *testing.T) {
// Record metrics
mc.Record("engine1", map[string]interface{}{
"uptime_seconds": 100.0,
"running": true,
"peers": 5,
})
// Retrieve metrics
metrics := mc.Get("engine1")
require.NotNil(t, metrics)
require.Equal(t, "engine1", metrics.Name)
require.Equal(t, 100.0, metrics.Values["uptime_seconds"])
// Record more for history
for i := 0; i < 5; i++ {
mc.Record("engine1", map[string]interface{}{
"uptime_seconds": float64(100 + i*10),
"running": true,
})
time.Sleep(10 * time.Millisecond)
}
metrics = mc.Get("engine1")
require.Len(t, metrics.History, 6) // Initial + 5 more
})
t.Run("Summary", func(t *testing.T) {
mc := orchestrator.NewMetricsCollector()
mc.Record("engine1", map[string]interface{}{
"uptime_seconds": 100.0,
"running": true,
})
mc.Record("engine2", map[string]interface{}{
"uptime_seconds": 200.0,
"running": true,
})
mc.Record("engine3", map[string]interface{}{
"uptime_seconds": 50.0,
"running": false,
})
summary := mc.Summary()
require.Equal(t, 3, summary["engines"])
require.Equal(t, 350.0, summary["total_uptime_seconds"])
require.Equal(t, 2, summary["healthy_engines"])
})
}
+20 -20
View File
@@ -3,7 +3,7 @@ set -e
export RUN_E2E="true"
# e.g.,
# ./scripts/tests.e2e.sh $DEFAULT_VERSION1 $DEFAULT_VERSION2 $DEFAULT_SUBNET_EVM_VERSION
# ./scripts/tests.e2e.sh $DEFAULT_VERSION1 $DEFAULT_VERSION2 $DEFAULT_EVM_VERSION
if ! [[ "$0" =~ scripts/tests.e2e.sh ]]; then
echo "must be run from repository root"
exit 255
@@ -11,29 +11,29 @@ fi
DEFAULT_VERSION_1=1.22.80
DEFAULT_VERSION_2=1.22.79
DEFAULT_SUBNET_EVM_VERSION=0.8.35
DEFAULT_EVM_VERSION=0.8.35
if [ $# == 0 ]; then
VERSION_1=$DEFAULT_VERSION_1
VERSION_2=$DEFAULT_VERSION_2
SUBNET_EVM_VERSION=$DEFAULT_SUBNET_EVM_VERSION
EVM_VERSION=$DEFAULT_EVM_VERSION
else
VERSION_1=$1
if [[ -z "${VERSION_1}" ]]; then
echo "Missing version argument!"
echo "Usage: ${0} [VERSION_1] [VERSION_2] [SUBNET_EVM_VERSION]" >> /dev/stderr
echo "Usage: ${0} [VERSION_1] [VERSION_2] [EVM_VERSION]" >> /dev/stderr
exit 255
fi
VERSION_2=$2
if [[ -z "${VERSION_2}" ]]; then
echo "Missing version argument!"
echo "Usage: ${0} [VERSION_1] [VERSION_2] [SUBNET_EVM_VERSION]" >> /dev/stderr
echo "Usage: ${0} [VERSION_1] [VERSION_2] [EVM_VERSION]" >> /dev/stderr
exit 255
fi
SUBNET_EVM_VERSION=$3
if [[ -z "${SUBNET_EVM_VERSION}" ]]; then
EVM_VERSION=$3
if [[ -z "${EVM_VERSION}" ]]; then
echo "Missing version argument!"
echo "Usage: ${0} [VERSION_1] [VERSION_2] [SUBNET_EVM_VERSION]" >> /dev/stderr
echo "Usage: ${0} [VERSION_1] [VERSION_2] [EVM_VERSION]" >> /dev/stderr
exit 255
fi
fi
@@ -41,7 +41,7 @@ fi
echo "Running e2e tests with:"
echo VERSION_1: ${VERSION_1}
echo VERSION_2: ${VERSION_2}
echo SUBNET_EVM_VERSION: ${SUBNET_EVM_VERSION}
echo EVM_VERSION: ${EVM_VERSION}
if [ ! -f /tmp/node-v${VERSION_1}/node ]
then
@@ -115,7 +115,7 @@ then
find /tmp/node-v${VERSION_2}
fi
if [ ! -f /tmp/evm-v${SUBNET_EVM_VERSION}/evm ]
if [ ! -f /tmp/evm-v${EVM_VERSION}/evm ]
then
############################
# download evm plugin
@@ -123,22 +123,22 @@ then
GOARCH=$(go env GOARCH)
GOOS=$(go env GOOS)
# evm releases are raw binaries named evm-plugin-{os}-{arch}
DOWNLOAD_URL=https://github.com/luxfi/evm/releases/download/v${SUBNET_EVM_VERSION}/evm-plugin-linux-${GOARCH}
DOWNLOAD_URL=https://github.com/luxfi/evm/releases/download/v${EVM_VERSION}/evm-plugin-linux-${GOARCH}
if [[ ${GOOS} == "darwin" ]]; then
DOWNLOAD_URL=https://github.com/luxfi/evm/releases/download/v${SUBNET_EVM_VERSION}/evm-plugin-darwin-${GOARCH}
DOWNLOAD_URL=https://github.com/luxfi/evm/releases/download/v${EVM_VERSION}/evm-plugin-darwin-${GOARCH}
fi
rm -rf /tmp/evm-v${SUBNET_EVM_VERSION}
mkdir -p /tmp/evm-v${SUBNET_EVM_VERSION}
rm -rf /tmp/evm-v${EVM_VERSION}
mkdir -p /tmp/evm-v${EVM_VERSION}
echo "downloading evm ${SUBNET_EVM_VERSION} at ${DOWNLOAD_URL}"
curl -L ${DOWNLOAD_URL} -o /tmp/evm-v${SUBNET_EVM_VERSION}/evm
chmod +x /tmp/evm-v${SUBNET_EVM_VERSION}/evm
echo "downloading evm ${EVM_VERSION} at ${DOWNLOAD_URL}"
curl -L ${DOWNLOAD_URL} -o /tmp/evm-v${EVM_VERSION}/evm
chmod +x /tmp/evm-v${EVM_VERSION}/evm
# NOTE: We are copying the evm binary here to a plugin hardcoded as srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy which corresponds to the VM name `subnetevm` used as such in the test
mkdir -p /tmp/node-v${VERSION_1}/plugins/
cp /tmp/evm-v${SUBNET_EVM_VERSION}/evm /tmp/node-v${VERSION_1}/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy
find /tmp/evm-v${SUBNET_EVM_VERSION}/evm
cp /tmp/evm-v${EVM_VERSION}/evm /tmp/node-v${VERSION_1}/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy
find /tmp/evm-v${EVM_VERSION}/evm
fi
############################
echo "building runner"
@@ -187,4 +187,4 @@ echo "running e2e tests"
--grpc-gateway-endpoint="0.0.0.0:8081" \
--node-path-1=/tmp/node-v${VERSION_1}/node \
--node-path-2=/tmp/node-v${VERSION_2}/node \
--subnet-evm-path=/tmp/evm-v${SUBNET_EVM_VERSION}/evm
--evm-path=/tmp/evm-v${EVM_VERSION}/evm
Executable
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff