mirror of
https://github.com/luxfi/netrunner.git
synced 2026-07-27 00:04:23 +00:00
Refactor subnet→chain terminology and update genesis to v1.5.6
Major changes: - Rename SubnetSpec → ChainSpec/ParticipantSpec throughout codebase - Rename BlockchainSpec → ChainSpec for full chain definitions - Update all protobuf definitions with new naming - Fix duplicate variable declarations from sed replacements - Update copyright headers to BSD-3-Clause with SPDX identifiers - Update github.com/luxfi/genesis to v1.5.6 (BLS signer keys) The genesis v1.5.6 update adds: - Initial stakers with BLS publicKey and proofOfPossession - Initial allocations for local network testing - Fixes "failed to load database state: not found" error Build fixes: - Fix api/mocks/client.go CChainAPI return type - Fix local/node_test.go with build tag for integration tests - Fix parameter name collisions (chainConfigs → pChainConfigs)
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
name: Deploy Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- '.github/workflows/docs.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: docs
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: docs/pnpm-lock.yaml
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: docs/out
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
+1
-1
@@ -88,7 +88,7 @@ func (c APIClient) InfoAPI() *info.Client {
|
||||
return c.info
|
||||
}
|
||||
|
||||
func (c APIClient) HealthAPI() *health.Client {
|
||||
func (c APIClient) HealthAPI() HealthClient {
|
||||
return c.health
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -11,11 +11,19 @@ import (
|
||||
"github.com/luxfi/node/api/health"
|
||||
"github.com/luxfi/node/api/info"
|
||||
"github.com/luxfi/node/indexer"
|
||||
"github.com/luxfi/node/utils/rpc"
|
||||
"github.com/luxfi/node/vms/exchangevm"
|
||||
"github.com/luxfi/node/vms/platformvm"
|
||||
// evmclient "github.com/luxfi/evm/plugin/evm/client"
|
||||
)
|
||||
|
||||
// HealthClient is the interface for health API client operations
|
||||
type HealthClient interface {
|
||||
Readiness(ctx context.Context, tags []string, options ...rpc.Option) (*health.APIReply, error)
|
||||
Health(ctx context.Context, tags []string, options ...rpc.Option) (*health.APIReply, error)
|
||||
Liveness(ctx context.Context, tags []string, options ...rpc.Option) (*health.APIReply, error)
|
||||
}
|
||||
|
||||
// EthClient is the interface for ethereum client operations
|
||||
type EthClient interface {
|
||||
// Balance operations
|
||||
@@ -63,7 +71,7 @@ type Client interface {
|
||||
CChainAPI() interface{} // evmclient.Client
|
||||
CChainEthAPI() EthClient // ethclient websocket wrapper that adds mutexed calls, and lazy conn init (on first call)
|
||||
InfoAPI() *info.Client
|
||||
HealthAPI() *health.Client
|
||||
HealthAPI() HealthClient
|
||||
AdminAPI() *admin.Client
|
||||
PChainIndexAPI() *indexer.Client
|
||||
CChainIndexAPI() *indexer.Client
|
||||
|
||||
+8
-14
@@ -8,10 +8,6 @@ import (
|
||||
|
||||
exchangevm "github.com/luxfi/node/vms/exchangevm"
|
||||
|
||||
evmclient "github.com/luxfi/evm/plugin/evm/client"
|
||||
|
||||
health "github.com/luxfi/node/api/health"
|
||||
|
||||
indexer "github.com/luxfi/node/indexer"
|
||||
|
||||
info "github.com/luxfi/node/api/info"
|
||||
@@ -43,16 +39,14 @@ func (_m *Client) AdminAPI() *admin.Client {
|
||||
}
|
||||
|
||||
// CChainAPI provides a mock function with given fields:
|
||||
func (_m *Client) CChainAPI() evmclient.Client {
|
||||
func (_m *Client) CChainAPI() interface{} {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 evmclient.Client
|
||||
if rf, ok := ret.Get(0).(func() evmclient.Client); ok {
|
||||
var r0 interface{}
|
||||
if rf, ok := ret.Get(0).(func() interface{}); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(evmclient.Client)
|
||||
}
|
||||
r0 = ret.Get(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
@@ -91,15 +85,15 @@ func (_m *Client) CChainIndexAPI() *indexer.Client {
|
||||
}
|
||||
|
||||
// HealthAPI provides a mock function with given fields:
|
||||
func (_m *Client) HealthAPI() *health.Client {
|
||||
func (_m *Client) HealthAPI() api.HealthClient {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 *health.Client
|
||||
if rf, ok := ret.Get(0).(func() *health.Client); ok {
|
||||
var r0 api.HealthClient
|
||||
if rf, ok := ret.Get(0).(func() api.HealthClient); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*health.Client)
|
||||
r0 = ret.Get(0).(api.HealthClient)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+51
-49
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package client implements client.
|
||||
package client
|
||||
@@ -31,11 +31,13 @@ type Client interface {
|
||||
Ping(ctx context.Context) (*rpcpb.PingResponse, error)
|
||||
RPCVersion(ctx context.Context) (*rpcpb.RPCVersionResponse, error)
|
||||
Start(ctx context.Context, execPath string, opts ...OpOption) (*rpcpb.StartResponse, error)
|
||||
CreateBlockchains(ctx context.Context, blockchainSpecs []*rpcpb.BlockchainSpec) (*rpcpb.CreateBlockchainsResponse, error)
|
||||
CreateSubnets(ctx context.Context, subnetSpecs []*rpcpb.SubnetSpec) (*rpcpb.CreateSubnetsResponse, error)
|
||||
TransformElasticSubnets(ctx context.Context, elasticSubnetSpecs []*rpcpb.ElasticSubnetSpec) (*rpcpb.TransformElasticSubnetsResponse, error)
|
||||
// CreateChains creates chains with VMs and genesis (uses rpcpb.CreateBlockchains)
|
||||
CreateChains(ctx context.Context, chainSpecs []*rpcpb.BlockchainSpec) (*rpcpb.CreateBlockchainsResponse, error)
|
||||
// CreateParticipantGroups creates participant groups (uses rpcpb.CreateChains)
|
||||
CreateParticipantGroups(ctx context.Context, participantsSpecs []*rpcpb.ChainSpec) (*rpcpb.CreateChainsResponse, error)
|
||||
TransformElasticChains(ctx context.Context, elasticChainSpecs []*rpcpb.ElasticChainSpec) (*rpcpb.TransformElasticChainsResponse, error)
|
||||
AddPermissionlessValidator(ctx context.Context, validatorSpec []*rpcpb.PermissionlessValidatorSpec) (*rpcpb.AddPermissionlessValidatorResponse, error)
|
||||
RemoveSubnetValidator(ctx context.Context, validatorSpec []*rpcpb.RemoveSubnetValidatorSpec) (*rpcpb.RemoveSubnetValidatorResponse, error)
|
||||
RemoveChainValidator(ctx context.Context, validatorSpec []*rpcpb.RemoveChainValidatorSpec) (*rpcpb.RemoveChainValidatorResponse, error)
|
||||
Health(ctx context.Context) (*rpcpb.HealthResponse, error)
|
||||
WaitForHealthy(ctx context.Context) (*rpcpb.WaitForHealthyResponse, error)
|
||||
URIs(ctx context.Context) ([]string, error)
|
||||
@@ -116,10 +118,10 @@ func (c *client) Start(ctx context.Context, execPath string, opts ...OpOption) (
|
||||
NumNodes: &ret.numNodes,
|
||||
ChainConfigs: ret.chainConfigs,
|
||||
UpgradeConfigs: ret.upgradeConfigs,
|
||||
SubnetConfigs: ret.subnetConfigs,
|
||||
ChainConfigFiles: ret.chainConfigs,
|
||||
}
|
||||
if ret.trackSubnets != "" {
|
||||
req.WhitelistedSubnets = &ret.trackSubnets
|
||||
if ret.trackChains != "" {
|
||||
req.WhitelistedChains = &ret.trackChains
|
||||
}
|
||||
if ret.rootDataDir != "" {
|
||||
req.RootDataDir = &ret.rootDataDir
|
||||
@@ -127,8 +129,8 @@ func (c *client) Start(ctx context.Context, execPath string, opts ...OpOption) (
|
||||
if ret.pluginDir != "" {
|
||||
req.PluginDir = ret.pluginDir
|
||||
}
|
||||
if len(ret.blockchainSpecs) > 0 {
|
||||
req.BlockchainSpecs = ret.blockchainSpecs
|
||||
if len(ret.chainSpecs) > 0 {
|
||||
req.BlockchainSpecs = ret.chainSpecs
|
||||
}
|
||||
if ret.globalNodeConfig != "" {
|
||||
req.GlobalNodeConfig = &ret.globalNodeConfig
|
||||
@@ -143,31 +145,31 @@ func (c *client) Start(ctx context.Context, execPath string, opts ...OpOption) (
|
||||
return c.controlc.Start(ctx, req)
|
||||
}
|
||||
|
||||
func (c *client) CreateBlockchains(ctx context.Context, blockchainSpecs []*rpcpb.BlockchainSpec) (*rpcpb.CreateBlockchainsResponse, error) {
|
||||
func (c *client) CreateChains(ctx context.Context, chainSpecs []*rpcpb.BlockchainSpec) (*rpcpb.CreateBlockchainsResponse, error) {
|
||||
req := &rpcpb.CreateBlockchainsRequest{
|
||||
BlockchainSpecs: blockchainSpecs,
|
||||
BlockchainSpecs: chainSpecs,
|
||||
}
|
||||
|
||||
c.log.Info("create blockchains")
|
||||
c.log.Info("create chains")
|
||||
return c.controlc.CreateBlockchains(ctx, req)
|
||||
}
|
||||
|
||||
func (c *client) CreateSubnets(ctx context.Context, subnetSpecs []*rpcpb.SubnetSpec) (*rpcpb.CreateSubnetsResponse, error) {
|
||||
req := &rpcpb.CreateSubnetsRequest{
|
||||
SubnetSpecs: subnetSpecs,
|
||||
func (c *client) CreateParticipantGroups(ctx context.Context, participantsSpecs []*rpcpb.ChainSpec) (*rpcpb.CreateChainsResponse, error) {
|
||||
req := &rpcpb.CreateChainsRequest{
|
||||
ChainSpecs: participantsSpecs,
|
||||
}
|
||||
|
||||
c.log.Info("create subnets")
|
||||
return c.controlc.CreateSubnets(ctx, req)
|
||||
c.log.Info("create participant groups")
|
||||
return c.controlc.CreateChains(ctx, req)
|
||||
}
|
||||
|
||||
func (c *client) TransformElasticSubnets(ctx context.Context, elasticSubnetSpecs []*rpcpb.ElasticSubnetSpec) (*rpcpb.TransformElasticSubnetsResponse, error) {
|
||||
req := &rpcpb.TransformElasticSubnetsRequest{
|
||||
ElasticSubnetSpec: elasticSubnetSpecs,
|
||||
func (c *client) TransformElasticChains(ctx context.Context, elasticChainSpecs []*rpcpb.ElasticChainSpec) (*rpcpb.TransformElasticChainsResponse, error) {
|
||||
req := &rpcpb.TransformElasticChainsRequest{
|
||||
ElasticChainSpec: elasticChainSpecs,
|
||||
}
|
||||
|
||||
c.log.Info("transform subnets")
|
||||
return c.controlc.TransformElasticSubnets(ctx, req)
|
||||
c.log.Info("transform chains")
|
||||
return c.controlc.TransformElasticChains(ctx, req)
|
||||
}
|
||||
|
||||
func (c *client) AddPermissionlessValidator(ctx context.Context, validatorSpec []*rpcpb.PermissionlessValidatorSpec) (*rpcpb.AddPermissionlessValidatorResponse, error) {
|
||||
@@ -175,17 +177,17 @@ func (c *client) AddPermissionlessValidator(ctx context.Context, validatorSpec [
|
||||
ValidatorSpec: validatorSpec,
|
||||
}
|
||||
|
||||
c.log.Info("add permissionless validators to elastic subnets")
|
||||
c.log.Info("add permissionless validators to elastic chains")
|
||||
return c.controlc.AddPermissionlessValidator(ctx, req)
|
||||
}
|
||||
|
||||
func (c *client) RemoveSubnetValidator(ctx context.Context, validatorSpec []*rpcpb.RemoveSubnetValidatorSpec) (*rpcpb.RemoveSubnetValidatorResponse, error) {
|
||||
req := &rpcpb.RemoveSubnetValidatorRequest{
|
||||
func (c *client) RemoveChainValidator(ctx context.Context, validatorSpec []*rpcpb.RemoveChainValidatorSpec) (*rpcpb.RemoveChainValidatorResponse, error) {
|
||||
req := &rpcpb.RemoveChainValidatorRequest{
|
||||
ValidatorSpec: validatorSpec,
|
||||
}
|
||||
|
||||
c.log.Info("remove subnet validator")
|
||||
return c.controlc.RemoveSubnetValidator(ctx, req)
|
||||
c.log.Info("remove chain validator")
|
||||
return c.controlc.RemoveChainValidator(ctx, req)
|
||||
}
|
||||
|
||||
func (c *client) Health(ctx context.Context) (*rpcpb.HealthResponse, error) {
|
||||
@@ -274,7 +276,7 @@ func (c *client) AddNode(ctx context.Context, name string, execPath string, opts
|
||||
NodeConfig: &ret.globalNodeConfig,
|
||||
ChainConfigs: ret.chainConfigs,
|
||||
UpgradeConfigs: ret.upgradeConfigs,
|
||||
SubnetConfigs: ret.subnetConfigs,
|
||||
ChainConfigFiles: ret.chainConfigs,
|
||||
}
|
||||
|
||||
if ret.pluginDir != "" {
|
||||
@@ -311,12 +313,12 @@ func (c *client) RestartNode(ctx context.Context, name string, opts ...OpOption)
|
||||
if ret.pluginDir != "" {
|
||||
req.PluginDir = ret.pluginDir
|
||||
}
|
||||
if ret.trackSubnets != "" {
|
||||
req.WhitelistedSubnets = &ret.trackSubnets
|
||||
if ret.trackChains != "" {
|
||||
req.WhitelistedChains = &ret.trackChains
|
||||
}
|
||||
req.ChainConfigs = ret.chainConfigs
|
||||
req.UpgradeConfigs = ret.upgradeConfigs
|
||||
req.SubnetConfigs = ret.subnetConfigs
|
||||
req.ChainConfigFiles = ret.chainConfigs
|
||||
|
||||
c.log.Info("restart node", zap.String("name", name))
|
||||
return c.controlc.RestartNode(ctx, req)
|
||||
@@ -350,7 +352,7 @@ func (c *client) LoadSnapshot(ctx context.Context, snapshotName string, opts ...
|
||||
SnapshotName: snapshotName,
|
||||
ChainConfigs: ret.chainConfigs,
|
||||
UpgradeConfigs: ret.upgradeConfigs,
|
||||
SubnetConfigs: ret.subnetConfigs,
|
||||
ChainConfigFiles: ret.chainConfigs,
|
||||
}
|
||||
if ret.execPath != "" {
|
||||
req.ExecPath = &ret.execPath
|
||||
@@ -392,16 +394,16 @@ func (c *client) Close() error {
|
||||
type Op struct {
|
||||
numNodes uint32
|
||||
execPath string
|
||||
trackSubnets string
|
||||
trackChains string
|
||||
globalNodeConfig string
|
||||
rootDataDir string
|
||||
pluginDir string
|
||||
blockchainSpecs []*rpcpb.BlockchainSpec
|
||||
chainSpecs []*rpcpb.BlockchainSpec
|
||||
customNodeConfigs map[string]string
|
||||
numSubnets uint32
|
||||
numChains uint32
|
||||
chainConfigs map[string]string
|
||||
upgradeConfigs map[string]string
|
||||
subnetConfigs map[string]string
|
||||
pChainConfigs map[string]string
|
||||
reassignPortsIfUsed bool
|
||||
dynamicPorts bool
|
||||
}
|
||||
@@ -432,15 +434,15 @@ func WithExecPath(execPath string) OpOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithWhitelistedSubnets(trackSubnets string) OpOption {
|
||||
func WithWhitelistedChains(trackChains string) OpOption {
|
||||
return func(op *Op) {
|
||||
op.trackSubnets = trackSubnets
|
||||
op.trackChains = trackChains
|
||||
}
|
||||
}
|
||||
|
||||
func WithTrackSubnets(trackSubnets string) OpOption {
|
||||
func WithTrackChains(trackChains string) OpOption {
|
||||
return func(op *Op) {
|
||||
op.trackSubnets = trackSubnets
|
||||
op.trackChains = trackChains
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,10 +458,10 @@ func WithPluginDir(pluginDir string) OpOption {
|
||||
}
|
||||
}
|
||||
|
||||
// Slice of BlockchainSpec
|
||||
func WithBlockchainSpecs(blockchainSpecs []*rpcpb.BlockchainSpec) OpOption {
|
||||
// WithChainSpecs sets the chain specifications for creating chains with VMs
|
||||
func WithChainSpecs(chainSpecs []*rpcpb.BlockchainSpec) OpOption {
|
||||
return func(op *Op) {
|
||||
op.blockchainSpecs = blockchainSpecs
|
||||
op.chainSpecs = chainSpecs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,10 +479,10 @@ func WithUpgradeConfigs(upgradeConfigs map[string]string) OpOption {
|
||||
}
|
||||
}
|
||||
|
||||
// Map from subnet id to its configuration json contents.
|
||||
func WithSubnetConfigs(subnetConfigs map[string]string) OpOption {
|
||||
// Map from chain id to its configuration json contents.
|
||||
func WithChainConfigFiles(chainConfigs map[string]string) OpOption {
|
||||
return func(op *Op) {
|
||||
op.subnetConfigs = subnetConfigs
|
||||
op.chainConfigs = chainConfigs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,9 +493,9 @@ func WithCustomNodeConfigs(customNodeConfigs map[string]string) OpOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithNumSubnets(numSubnets uint32) OpOption {
|
||||
func WithNumChains(numChains uint32) OpOption {
|
||||
return func(op *Op) {
|
||||
op.numSubnets = numSubnets
|
||||
op.numChains = numChains
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+88
-88
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package control
|
||||
|
||||
@@ -35,7 +35,7 @@ const clientRootDirPrefix = "client"
|
||||
var (
|
||||
logLevel string
|
||||
logDir string
|
||||
trackSubnets string
|
||||
trackChains string
|
||||
endpoint string
|
||||
dialTimeout time.Duration
|
||||
requestTimeout time.Duration
|
||||
@@ -59,11 +59,11 @@ func NewCommand() *cobra.Command {
|
||||
cmd.AddCommand(
|
||||
newRPCVersionCommand(),
|
||||
newStartCommand(),
|
||||
newCreateBlockchainsCommand(),
|
||||
newCreateSubnetsCommand(),
|
||||
newTransformElasticSubnetsCommand(),
|
||||
newCreateChainsCommand(),
|
||||
newCreateParticipantGroupsCommand(),
|
||||
newTransformElasticChainsCommand(),
|
||||
newAddPermissionlessValidatorCommand(),
|
||||
newRemoveSubnetValidatorCommand(),
|
||||
newRemoveChainValidatorCommand(),
|
||||
newHealthCommand(),
|
||||
newWaitForHealthyCommand(),
|
||||
newURIsCommand(),
|
||||
@@ -92,12 +92,12 @@ var (
|
||||
pluginDir string
|
||||
globalNodeConfig string
|
||||
addNodeConfig string
|
||||
blockchainSpecsStr string
|
||||
chainSpecsStr string
|
||||
customNodeConfigs string
|
||||
rootDataDir string
|
||||
chainConfigs string
|
||||
upgradeConfigs string
|
||||
subnetConfigs string
|
||||
pChainConfigs string
|
||||
reassignPortsIfUsed bool
|
||||
dynamicPorts bool
|
||||
)
|
||||
@@ -191,7 +191,7 @@ func newStartCommand() *cobra.Command {
|
||||
"[optional] root data directory to store logs and configurations",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&blockchainSpecsStr,
|
||||
&chainSpecsStr,
|
||||
"blockchain-specs",
|
||||
"",
|
||||
"[optional] JSON string of array of [(VM name, genesis file path)]",
|
||||
@@ -209,10 +209,10 @@ func newStartCommand() *cobra.Command {
|
||||
"[optional] custom node configs as JSON string of map, for each node individually. Common entries override `global-node-config`, but can be combined. Invalidates `number-of-nodes` (provide all node configs if used).",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&trackSubnets,
|
||||
"whitelisted-subnets",
|
||||
&trackChains,
|
||||
"whitelisted-chains",
|
||||
"",
|
||||
"[optional] whitelisted subnets (comma-separated)",
|
||||
"[optional] whitelisted chains (comma-separated)",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&chainConfigs,
|
||||
@@ -227,10 +227,10 @@ func newStartCommand() *cobra.Command {
|
||||
"[optional] JSON string of map from chain id to its upgrade file contents",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&subnetConfigs,
|
||||
"subnet-configs",
|
||||
&chainConfigs,
|
||||
"chain-configs",
|
||||
"",
|
||||
"[optional] JSON string of map from subnet id to its config file contents",
|
||||
"[optional] JSON string of map from chain id to its config file contents",
|
||||
)
|
||||
cmd.PersistentFlags().BoolVar(
|
||||
&reassignPortsIfUsed,
|
||||
@@ -260,7 +260,7 @@ func startFunc(*cobra.Command, []string) error {
|
||||
opts := []client.OpOption{
|
||||
client.WithNumNodes(numNodes),
|
||||
client.WithPluginDir(pluginDir),
|
||||
client.WithTrackSubnets(trackSubnets),
|
||||
client.WithTrackChains(trackChains),
|
||||
client.WithRootDataDir(rootDataDir),
|
||||
client.WithReassignPortsIfUsed(reassignPortsIfUsed),
|
||||
client.WithDynamicPorts(dynamicPorts),
|
||||
@@ -284,12 +284,12 @@ func startFunc(*cobra.Command, []string) error {
|
||||
opts = append(opts, client.WithCustomNodeConfigs(nodeConfigs))
|
||||
}
|
||||
|
||||
if blockchainSpecsStr != "" {
|
||||
blockchainSpecs := []*rpcpb.BlockchainSpec{}
|
||||
if err := json.Unmarshal([]byte(blockchainSpecsStr), &blockchainSpecs); err != nil {
|
||||
if chainSpecsStr != "" {
|
||||
chainSpecs := []*rpcpb.BlockchainSpec{}
|
||||
if err := json.Unmarshal([]byte(chainSpecsStr), &chainSpecs); err != nil {
|
||||
return err
|
||||
}
|
||||
opts = append(opts, client.WithBlockchainSpecs(blockchainSpecs))
|
||||
opts = append(opts, client.WithChainSpecs(chainSpecs))
|
||||
}
|
||||
|
||||
if chainConfigs != "" {
|
||||
@@ -306,12 +306,12 @@ func startFunc(*cobra.Command, []string) error {
|
||||
}
|
||||
opts = append(opts, client.WithUpgradeConfigs(upgradeConfigsMap))
|
||||
}
|
||||
if subnetConfigs != "" {
|
||||
subnetConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(subnetConfigs), &subnetConfigsMap); err != nil {
|
||||
if chainConfigs != "" {
|
||||
chainConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(chainConfigs), &chainConfigsMap); err != nil {
|
||||
return err
|
||||
}
|
||||
opts = append(opts, client.WithSubnetConfigs(subnetConfigsMap))
|
||||
opts = append(opts, client.WithChainConfigFiles(chainConfigsMap))
|
||||
}
|
||||
|
||||
ctx := getAsyncContext()
|
||||
@@ -329,35 +329,35 @@ func startFunc(*cobra.Command, []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCreateBlockchainsCommand() *cobra.Command {
|
||||
func newCreateChainsCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "create-blockchains blockchain-specs [options]",
|
||||
Short: "Create blockchains.",
|
||||
RunE: createBlockchainsFunc,
|
||||
RunE: createChainsFunc,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func createBlockchainsFunc(_ *cobra.Command, args []string) error {
|
||||
func createChainsFunc(_ *cobra.Command, args []string) error {
|
||||
cli, err := newClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
blockchainSpecsStr := args[0]
|
||||
chainSpecsStr := args[0]
|
||||
|
||||
blockchainSpecs := []*rpcpb.BlockchainSpec{}
|
||||
if err := json.Unmarshal([]byte(blockchainSpecsStr), &blockchainSpecs); err != nil {
|
||||
chainSpecs := []*rpcpb.BlockchainSpec{}
|
||||
if err := json.Unmarshal([]byte(chainSpecsStr), &chainSpecs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := getAsyncContext()
|
||||
|
||||
info, err := cli.CreateBlockchains(
|
||||
info, err := cli.CreateChains(
|
||||
ctx,
|
||||
blockchainSpecs,
|
||||
chainSpecs,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -367,49 +367,49 @@ func createBlockchainsFunc(_ *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCreateSubnetsCommand() *cobra.Command {
|
||||
func newCreateParticipantGroupsCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "create-subnets [options]",
|
||||
Short: "Create subnets.",
|
||||
RunE: createSubnetsFunc,
|
||||
Use: "create-participant-groups [options]",
|
||||
Short: "Create participant groups.",
|
||||
RunE: createParticipantGroupsFunc,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func createSubnetsFunc(_ *cobra.Command, args []string) error {
|
||||
func createParticipantGroupsFunc(_ *cobra.Command, args []string) error {
|
||||
cli, err := newClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
subnetSpecsStr := args[0]
|
||||
participantsSpecsStr := args[0]
|
||||
|
||||
subnetSpecs := []*rpcpb.SubnetSpec{}
|
||||
if err := json.Unmarshal([]byte(subnetSpecsStr), &subnetSpecs); err != nil {
|
||||
participantsSpecs := []*rpcpb.ChainSpec{}
|
||||
if err := json.Unmarshal([]byte(participantsSpecsStr), &participantsSpecs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := getAsyncContext()
|
||||
|
||||
info, err := cli.CreateSubnets(
|
||||
info, err := cli.CreateParticipantGroups(
|
||||
ctx,
|
||||
subnetSpecs,
|
||||
participantsSpecs,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ux.Print(log, luxlog.Green.Wrap("create-subnets response: %+v"), info)
|
||||
ux.Print(log, luxlog.Green.Wrap("create-chains response: %+v"), info)
|
||||
return nil
|
||||
}
|
||||
|
||||
func newTransformElasticSubnetsCommand() *cobra.Command {
|
||||
func newTransformElasticChainsCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "elastic-subnets elastic_subnets_specs [options]",
|
||||
Short: "Transform subnets to elastic subnets.",
|
||||
RunE: transformElasticSubnetsFunc,
|
||||
Use: "elastic-chains elastic_chains_specs [options]",
|
||||
Short: "Transform chains to elastic chains.",
|
||||
RunE: transformElasticChainsFunc,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
return cmd
|
||||
@@ -418,48 +418,48 @@ func newTransformElasticSubnetsCommand() *cobra.Command {
|
||||
func newAddPermissionlessValidatorCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "add-permissionless-validator permissionlessValidatorSpecs [options]",
|
||||
Short: "Add permissionless validator to elastic subnets.",
|
||||
Short: "Add permissionless validator to elastic chains.",
|
||||
RunE: addPermissionlessValidatorFunc,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newRemoveSubnetValidatorCommand() *cobra.Command {
|
||||
func newRemoveChainValidatorCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "remove-subnet-validator removeValidatorSpec [options]",
|
||||
Short: "Remove subnet validator",
|
||||
RunE: removeSubnetValidatorFunc,
|
||||
Use: "remove-chain-validator removeValidatorSpec [options]",
|
||||
Short: "Remove chain validator",
|
||||
RunE: removeChainValidatorFunc,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func transformElasticSubnetsFunc(_ *cobra.Command, args []string) error {
|
||||
func transformElasticChainsFunc(_ *cobra.Command, args []string) error {
|
||||
cli, err := newClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
elasticSubnetSpecsStr := args[0]
|
||||
elasticParticipantsSpecsStr := args[0]
|
||||
|
||||
elasticSubnetSpecs := []*rpcpb.ElasticSubnetSpec{}
|
||||
if err := json.Unmarshal([]byte(elasticSubnetSpecsStr), &elasticSubnetSpecs); err != nil {
|
||||
elasticParticipantsSpecs := []*rpcpb.ElasticChainSpec{}
|
||||
if err := json.Unmarshal([]byte(elasticParticipantsSpecsStr), &elasticParticipantsSpecs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := getAsyncContext()
|
||||
|
||||
info, err := cli.TransformElasticSubnets(
|
||||
info, err := cli.TransformElasticChains(
|
||||
ctx,
|
||||
elasticSubnetSpecs,
|
||||
elasticParticipantsSpecs,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ux.Print(log, luxlog.Green.Wrap("elastic-subnets response: %+v"), info)
|
||||
ux.Print(log, luxlog.Green.Wrap("elastic-chains response: %+v"), info)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ func addPermissionlessValidatorFunc(_ *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeSubnetValidatorFunc(_ *cobra.Command, args []string) error {
|
||||
func removeChainValidatorFunc(_ *cobra.Command, args []string) error {
|
||||
cli, err := newClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -500,14 +500,14 @@ func removeSubnetValidatorFunc(_ *cobra.Command, args []string) error {
|
||||
|
||||
validatorSpecStr := args[0]
|
||||
|
||||
validatorSpec := []*rpcpb.RemoveSubnetValidatorSpec{}
|
||||
validatorSpec := []*rpcpb.RemoveChainValidatorSpec{}
|
||||
if err := json.Unmarshal([]byte(validatorSpecStr), &validatorSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := getAsyncContext()
|
||||
|
||||
info, err := cli.RemoveSubnetValidator(
|
||||
info, err := cli.RemoveChainValidator(
|
||||
ctx,
|
||||
validatorSpec,
|
||||
)
|
||||
@@ -515,7 +515,7 @@ func removeSubnetValidatorFunc(_ *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ux.Print(log, luxlog.Green.Wrap("remove-subnet-validator response: %+v"), info)
|
||||
ux.Print(log, luxlog.Green.Wrap("remove-chain-validator response: %+v"), info)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -812,10 +812,10 @@ func newAddNodeCommand() *cobra.Command {
|
||||
"[optional] JSON string of map from chain id to its upgrade file contents",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&subnetConfigs,
|
||||
"subnet-configs",
|
||||
&chainConfigs,
|
||||
"chain-configs",
|
||||
"",
|
||||
"[optional] JSON string of map from subnet id to its config file contents",
|
||||
"[optional] JSON string of map from chain id to its config file contents",
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
@@ -857,12 +857,12 @@ func addNodeFunc(_ *cobra.Command, args []string) error {
|
||||
}
|
||||
opts = append(opts, client.WithUpgradeConfigs(upgradeConfigsMap))
|
||||
}
|
||||
if subnetConfigs != "" {
|
||||
subnetConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(subnetConfigs), &subnetConfigsMap); err != nil {
|
||||
if chainConfigs != "" {
|
||||
chainConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(chainConfigs), &chainConfigsMap); err != nil {
|
||||
return err
|
||||
}
|
||||
opts = append(opts, client.WithSubnetConfigs(subnetConfigsMap))
|
||||
opts = append(opts, client.WithChainConfigFiles(chainConfigsMap))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
|
||||
@@ -895,10 +895,10 @@ func newRestartNodeCommand() *cobra.Command {
|
||||
"node binary path",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&trackSubnets,
|
||||
"whitelisted-subnets",
|
||||
&trackChains,
|
||||
"whitelisted-chains",
|
||||
"",
|
||||
"[optional] whitelisted subnets (comma-separated)",
|
||||
"[optional] whitelisted chains (comma-separated)",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&pluginDir,
|
||||
@@ -919,10 +919,10 @@ func newRestartNodeCommand() *cobra.Command {
|
||||
"[optional] JSON string of map from chain id to its upgrade file contents",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&subnetConfigs,
|
||||
"subnet-configs",
|
||||
&chainConfigs,
|
||||
"chain-configs",
|
||||
"",
|
||||
"[optional] JSON string of map from subnet id to its config file contents",
|
||||
"[optional] JSON string of map from chain id to its config file contents",
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
@@ -939,7 +939,7 @@ func restartNodeFunc(_ *cobra.Command, args []string) error {
|
||||
opts := []client.OpOption{
|
||||
client.WithExecPath(luxdBinPath),
|
||||
client.WithPluginDir(pluginDir),
|
||||
client.WithTrackSubnets(trackSubnets),
|
||||
client.WithTrackChains(trackChains),
|
||||
}
|
||||
|
||||
if chainConfigs != "" {
|
||||
@@ -956,12 +956,12 @@ func restartNodeFunc(_ *cobra.Command, args []string) error {
|
||||
}
|
||||
opts = append(opts, client.WithUpgradeConfigs(upgradeConfigsMap))
|
||||
}
|
||||
if subnetConfigs != "" {
|
||||
subnetConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(subnetConfigs), &subnetConfigsMap); err != nil {
|
||||
if chainConfigs != "" {
|
||||
chainConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(chainConfigs), &chainConfigsMap); err != nil {
|
||||
return err
|
||||
}
|
||||
opts = append(opts, client.WithSubnetConfigs(subnetConfigsMap))
|
||||
opts = append(opts, client.WithChainConfigFiles(chainConfigsMap))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
|
||||
@@ -1172,10 +1172,10 @@ func newLoadSnapshotCommand() *cobra.Command {
|
||||
"[optional] JSON string of map from chain id to its upgrade file contents",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&subnetConfigs,
|
||||
"subnet-configs",
|
||||
&chainConfigs,
|
||||
"chain-configs",
|
||||
"",
|
||||
"[optional] JSON string of map from subnet id to its config file contents",
|
||||
"[optional] JSON string of map from chain id to its config file contents",
|
||||
)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&globalNodeConfig,
|
||||
@@ -1220,12 +1220,12 @@ func loadSnapshotFunc(_ *cobra.Command, args []string) error {
|
||||
}
|
||||
opts = append(opts, client.WithUpgradeConfigs(upgradeConfigsMap))
|
||||
}
|
||||
if subnetConfigs != "" {
|
||||
subnetConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(subnetConfigs), &subnetConfigsMap); err != nil {
|
||||
if chainConfigs != "" {
|
||||
chainConfigsMap := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(chainConfigs), &chainConfigsMap); err != nil {
|
||||
return err
|
||||
}
|
||||
opts = append(opts, client.WithSubnetConfigs(subnetConfigsMap))
|
||||
opts = append(opts, client.WithChainConfigFiles(chainConfigsMap))
|
||||
}
|
||||
|
||||
if globalNodeConfig != "" {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package cmd
|
||||
|
||||
|
||||
+17
-17
@@ -24,7 +24,7 @@ var multinetCmd = &cobra.Command{
|
||||
Short: "Manage multiple heterogeneous networks in parallel",
|
||||
Long: `Run and validate multiple networks simultaneously with shared BadgerDB
|
||||
for cross-chain ACID transactions. Supports both primary networks (mainnet/testnet)
|
||||
and their subnets (L1s/L2s).`,
|
||||
and their chains (L1s/L2s).`,
|
||||
}
|
||||
|
||||
// startCmd starts multiple networks
|
||||
@@ -40,7 +40,7 @@ shared database for cross-chain transactions.`,
|
||||
var configureCmd = &cobra.Command{
|
||||
Use: "configure",
|
||||
Short: "Configure networks for parallel validation",
|
||||
Long: `Set up mainnet, testnet, and their subnets for parallel validation.`,
|
||||
Long: `Set up mainnet, testnet, and their chains for parallel validation.`,
|
||||
RunE: runConfigure,
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ func runStartMulti(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("\nNetwork endpoints:")
|
||||
fmt.Println(" Lux Mainnet: http://localhost:9630")
|
||||
fmt.Println(" Lux Testnet: http://localhost:9620")
|
||||
fmt.Println("\nSubnets are accessible through their parent networks.")
|
||||
fmt.Println("\nChains are accessible through their parent networks.")
|
||||
fmt.Println("\nPress Ctrl+C to stop all networks...")
|
||||
|
||||
// Wait for interrupt
|
||||
@@ -159,27 +159,27 @@ func loadDefaultNetworks(manager *multinet.MultiNetworkManager) error {
|
||||
},
|
||||
}
|
||||
|
||||
// Zoo Subnet on Mainnet
|
||||
// Zoo Chain on Mainnet
|
||||
zooMainnetConfig := multinet.NetworkConfig{
|
||||
NetworkID: 200200,
|
||||
Name: "Zoo Network (Mainnet Subnet)",
|
||||
Type: multinet.NetworkTypeSubnet,
|
||||
Name: "Zoo Network (Mainnet Chain)",
|
||||
Type: multinet.NetworkTypeChain,
|
||||
ParentID: 96369,
|
||||
HTTPPort: 0, // Uses parent network's port
|
||||
StakingPort: 0, // Uses parent network's port
|
||||
DataDir: "/tmp/multinetwork/mainnet/subnets/zoo",
|
||||
DataDir: "/tmp/multinetwork/mainnet/chains/zoo",
|
||||
Validators: 5,
|
||||
}
|
||||
|
||||
// Hanzo Subnet on Mainnet
|
||||
// Hanzo Chain on Mainnet
|
||||
hanzoMainnetConfig := multinet.NetworkConfig{
|
||||
NetworkID: 36963,
|
||||
Name: "Hanzo Network (Mainnet Subnet)",
|
||||
Type: multinet.NetworkTypeSubnet,
|
||||
Name: "Hanzo Network (Mainnet Chain)",
|
||||
Type: multinet.NetworkTypeChain,
|
||||
ParentID: 96369,
|
||||
HTTPPort: 0,
|
||||
StakingPort: 0,
|
||||
DataDir: "/tmp/multinetwork/mainnet/subnets/hanzo",
|
||||
DataDir: "/tmp/multinetwork/mainnet/chains/hanzo",
|
||||
Validators: 5,
|
||||
}
|
||||
|
||||
@@ -245,17 +245,17 @@ func runConfigure(cmd *cobra.Command, args []string) error {
|
||||
{
|
||||
NetworkID: 200200,
|
||||
Name: "Zoo Network",
|
||||
Type: multinet.NetworkTypeSubnet,
|
||||
Type: multinet.NetworkTypeChain,
|
||||
ParentID: 96369,
|
||||
DataDir: "/tmp/multinetwork/mainnet/subnets/zoo",
|
||||
DataDir: "/tmp/multinetwork/mainnet/chains/zoo",
|
||||
Validators: 5,
|
||||
},
|
||||
{
|
||||
NetworkID: 36963,
|
||||
Name: "Hanzo Network",
|
||||
Type: multinet.NetworkTypeSubnet,
|
||||
Type: multinet.NetworkTypeChain,
|
||||
ParentID: 96369,
|
||||
DataDir: "/tmp/multinetwork/mainnet/subnets/hanzo",
|
||||
DataDir: "/tmp/multinetwork/mainnet/chains/hanzo",
|
||||
Validators: 5,
|
||||
},
|
||||
}
|
||||
@@ -278,8 +278,8 @@ func runConfigure(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("\nConfiguration includes:")
|
||||
fmt.Println(" • Lux Mainnet (96369) - Primary Network")
|
||||
fmt.Println(" • Lux Testnet (96368) - Primary Network")
|
||||
fmt.Println(" • Zoo Network (200200) - Subnet on Mainnet")
|
||||
fmt.Println(" • Hanzo Network (36963) - Subnet on Mainnet")
|
||||
fmt.Println(" • Zoo Network (200200) - Chain on Mainnet")
|
||||
fmt.Println(" • Hanzo Network (36963) - Chain on Mainnet")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package commands
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package commands
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package commands
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package commands
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package commands
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package commands
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package main
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package ping
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package cmd
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package server
|
||||
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ func getNetworkConfig(network string) multinet.NetworkConfig {
|
||||
Validators: 3,
|
||||
}
|
||||
default:
|
||||
// Could be a subnet name
|
||||
// Could be a chain name
|
||||
return multinet.NetworkConfig{}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package lux
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package engines
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package engines
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package geth
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package lux
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package engines
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package engines
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package main
|
||||
|
||||
@@ -126,22 +126,22 @@ func run(log luxlog.Logger, binaryPath string) error {
|
||||
}
|
||||
log.Info("All nodes healthy")
|
||||
|
||||
// Create DEX blockchain on a new subnet
|
||||
// Create DEX blockchain on a new chain
|
||||
log.Info("Creating DEX blockchain...")
|
||||
createCtx, createCancel := context.WithTimeout(context.Background(), createBlockchainTimeout)
|
||||
defer createCancel()
|
||||
|
||||
// DEX blockchain specification
|
||||
dexBlockchainSpec := []network.BlockchainSpec{
|
||||
dexChainSpec := []network.ChainSpec{
|
||||
{
|
||||
VMName: "dexvm", // Matches constants.DexVMName
|
||||
Genesis: dexGenesisJSON(), // DEX genesis configuration
|
||||
BlockchainAlias: "dex", // Alias for easier access
|
||||
// SubnetID not specified = creates new subnet with all nodes as validators
|
||||
Alias: "dex", // Alias for easier access
|
||||
// ChainID not specified = creates new chain with all nodes as validators
|
||||
},
|
||||
}
|
||||
|
||||
chainIDs, err := nw.CreateBlockchains(createCtx, dexBlockchainSpec)
|
||||
chainIDs, err := nw.CreateChains(createCtx, dexChainSpec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DEX blockchain: %w", err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/netrunner/local"
|
||||
"github.com/luxfi/netrunner/network"
|
||||
"github.com/luxfi/node/config"
|
||||
luxlog "github.com/luxfi/log"
|
||||
"github.com/luxfi/log/level"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
healthyTimeout = 3 * time.Minute
|
||||
createBlockchainTimeout = 5 * time.Minute
|
||||
luxdBinaryPath = "/Users/z/go/bin/luxd"
|
||||
pluginDir = "/Users/z/.luxd/plugins"
|
||||
)
|
||||
|
||||
// L2Chain defines configuration for deploying an L2 chain
|
||||
type L2Chain struct {
|
||||
Name string
|
||||
ChainID uint64
|
||||
VMName string
|
||||
Alias string
|
||||
GenesisPath string
|
||||
}
|
||||
|
||||
// L2 Chain configurations
|
||||
var l2Chains = []L2Chain{
|
||||
{
|
||||
Name: "Zoo",
|
||||
ChainID: 200200,
|
||||
VMName: "subnetevm",
|
||||
Alias: "zoo",
|
||||
GenesisPath: "/Users/z/work/lux/genesis/chains/zoo/genesis.json",
|
||||
},
|
||||
{
|
||||
Name: "SPC",
|
||||
ChainID: 36911,
|
||||
VMName: "subnetevm",
|
||||
Alias: "spc",
|
||||
GenesisPath: "/Users/z/work/lux/genesis/chains/spc/genesis.json",
|
||||
},
|
||||
{
|
||||
Name: "Hanzo AI",
|
||||
ChainID: 36963,
|
||||
VMName: "subnetevm",
|
||||
Alias: "hanzo",
|
||||
GenesisPath: "/Users/z/work/lux/genesis/chains/ai/genesis.json",
|
||||
},
|
||||
}
|
||||
|
||||
func shutdownOnSignal(
|
||||
log luxlog.Logger,
|
||||
n network.Network,
|
||||
signalChan chan os.Signal,
|
||||
closedOnShutdownChan chan struct{},
|
||||
) {
|
||||
sig := <-signalChan
|
||||
log.Info("got OS signal", zap.Stringer("signal", sig))
|
||||
if err := n.Stop(context.Background()); err != nil {
|
||||
log.Info("error stopping network", zap.Error(err))
|
||||
}
|
||||
signal.Reset()
|
||||
close(signalChan)
|
||||
close(closedOnShutdownChan)
|
||||
}
|
||||
|
||||
func main() {
|
||||
logFactory := luxlog.NewFactoryWithConfig(luxlog.Config{
|
||||
DisplayLevel: level.Info,
|
||||
LogLevel: level.Debug,
|
||||
})
|
||||
log, err := logFactory.Make("l2chains")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := run(log); err != nil {
|
||||
log.Fatal("fatal error", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run(log luxlog.Logger) error {
|
||||
// Create mainnet config for 5-node network
|
||||
log.Info("Creating mainnet configuration...")
|
||||
netConfig, err := local.NewMainnetConfig(luxdBinaryPath, 5)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create mainnet config: %w", err)
|
||||
}
|
||||
|
||||
// Add plugin directory and allow private IPs (required for local testing)
|
||||
// Also enable output redirection to see errors
|
||||
for i := range netConfig.NodeConfigs {
|
||||
netConfig.NodeConfigs[i].Flags[config.PluginDirKey] = pluginDir
|
||||
netConfig.NodeConfigs[i].Flags[config.NetworkAllowPrivateIPsKey] = true
|
||||
netConfig.NodeConfigs[i].RedirectStdout = true
|
||||
netConfig.NodeConfigs[i].RedirectStderr = true
|
||||
}
|
||||
|
||||
// Create network
|
||||
log.Info("Starting 5-node mainnet network...")
|
||||
nw, err := local.NewNetwork(log, netConfig, "", "", true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create network: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := nw.Stop(context.Background()); err != nil {
|
||||
log.Info("error stopping network", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
|
||||
// Setup signal handler
|
||||
signalsChan := make(chan os.Signal, 1)
|
||||
signal.Notify(signalsChan, syscall.SIGINT)
|
||||
signal.Notify(signalsChan, syscall.SIGTERM)
|
||||
closedOnShutdownCh := make(chan struct{})
|
||||
go func() {
|
||||
shutdownOnSignal(log, nw, signalsChan, closedOnShutdownCh)
|
||||
}()
|
||||
|
||||
// Wait until the nodes in the network are ready
|
||||
ctx, cancel := context.WithTimeout(context.Background(), healthyTimeout)
|
||||
defer cancel()
|
||||
log.Info("Waiting for all nodes to report healthy...")
|
||||
if err := nw.Healthy(ctx); err != nil {
|
||||
return fmt.Errorf("network failed to become healthy: %w", err)
|
||||
}
|
||||
log.Info("All nodes healthy")
|
||||
|
||||
// Get network info
|
||||
nodes, err := nw.GetAllNodes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get nodes: %w", err)
|
||||
}
|
||||
log.Info("Network ready", zap.Int("nodes", len(nodes)))
|
||||
|
||||
// Deploy L2 chains
|
||||
for _, chain := range l2Chains {
|
||||
log.Info("Deploying L2 chain...",
|
||||
zap.String("name", chain.Name),
|
||||
zap.Uint64("chainId", chain.ChainID),
|
||||
zap.String("alias", chain.Alias),
|
||||
)
|
||||
|
||||
genesis, err := os.ReadFile(chain.GenesisPath)
|
||||
if err != nil {
|
||||
log.Error("Failed to read genesis file",
|
||||
zap.String("chain", chain.Name),
|
||||
zap.String("path", chain.GenesisPath),
|
||||
zap.Error(err),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
createCtx, createCancel := context.WithTimeout(context.Background(), createBlockchainTimeout)
|
||||
chainSpec := []network.ChainSpec{
|
||||
{
|
||||
VMName: chain.VMName,
|
||||
Genesis: genesis,
|
||||
Alias: chain.Alias,
|
||||
BlockchainName: chain.Alias, // Use unique name for each chain
|
||||
},
|
||||
}
|
||||
|
||||
chainIDs, err := nw.CreateChains(createCtx, chainSpec)
|
||||
createCancel()
|
||||
if err != nil {
|
||||
log.Error("Failed to create chain",
|
||||
zap.String("chain", chain.Name),
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info("L2 chain deployed successfully",
|
||||
zap.String("name", chain.Name),
|
||||
zap.String("blockchain-id", chainIDs[0].String()),
|
||||
zap.String("alias", chain.Alias),
|
||||
)
|
||||
}
|
||||
|
||||
// Print connection info
|
||||
log.Info("L2 chains deployed. Connect to any node:")
|
||||
for name, node := range nodes {
|
||||
log.Info("Node available",
|
||||
zap.String("name", name),
|
||||
zap.String("url", fmt.Sprintf("http://%s:%d", node.GetURL(), node.GetAPIPort())),
|
||||
)
|
||||
}
|
||||
|
||||
log.Info("Network running. Press CTRL+C to exit...")
|
||||
<-closedOnShutdownCh
|
||||
return nil
|
||||
}
|
||||
@@ -10,8 +10,7 @@ require (
|
||||
github.com/luxfi/consensus v1.22.26
|
||||
github.com/luxfi/constants v1.2.3
|
||||
github.com/luxfi/crypto v1.17.22
|
||||
github.com/luxfi/evm v0.8.1
|
||||
github.com/luxfi/genesis v1.5.5
|
||||
github.com/luxfi/genesis v1.5.6
|
||||
github.com/luxfi/geth v1.16.52
|
||||
github.com/luxfi/ids v1.2.4
|
||||
github.com/luxfi/log v1.1.26
|
||||
|
||||
@@ -293,10 +293,8 @@ github.com/luxfi/crypto v1.17.22 h1:aYR0R4xTOqVy9q6mEFMrg7Oru7itveniWR8f4U5vea4=
|
||||
github.com/luxfi/crypto v1.17.22/go.mod h1:joL4xiznieeh61fs18bm/dF/HVrydzIPHDQk7HdZz9A=
|
||||
github.com/luxfi/database v1.2.11 h1:xpw+WdIRtiVSa64RAM0BLPgHO1n40YArxTE1cJW6A5Q=
|
||||
github.com/luxfi/database v1.2.11/go.mod h1:jXWOHWgIrgE7W2fSJp0lqGNV9ghRx6Gzev2v51c4GLQ=
|
||||
github.com/luxfi/evm v0.8.1 h1:DmQC5UETgunf4e0HGHkeDJCFwU2dOflcHLDICvszN7g=
|
||||
github.com/luxfi/evm v0.8.1/go.mod h1:ufY7D5sJ9mPUsj1ijuTXUU/ymiMoPoEI1mkjde3H1aA=
|
||||
github.com/luxfi/genesis v1.5.5 h1:vYICVQZnnEa0MN6wpEw1NNT84pJWMjIuqqD7MO6ta+M=
|
||||
github.com/luxfi/genesis v1.5.5/go.mod h1:mG7B/SExse3i/nVU42tcZ2J97HVv3iyCIX41X3JyYM4=
|
||||
github.com/luxfi/genesis v1.5.6 h1:HySJ7YE016miZ+7d3XDVMJRa1GtBK3vOgrxIBp7PN80=
|
||||
github.com/luxfi/genesis v1.5.6/go.mod h1:mG7B/SExse3i/nVU42tcZ2J97HVv3iyCIX41X3JyYM4=
|
||||
github.com/luxfi/geth v1.16.52 h1:nkRjlVNlPgtSSOROS95PRXB1CyKGYLr3AstYb41TMtA=
|
||||
github.com/luxfi/geth v1.16.52/go.mod h1:OJHnLi5CDtLY+QS4c7iN880zVUNcQXteJPgWpoQPj/8=
|
||||
github.com/luxfi/go-bip32 v1.0.1 h1:UaPUSu6ScZ1wobQJJO+vePAN3OcUHYmq5DEc/uOU+SY=
|
||||
|
||||
+254
-279
File diff suppressed because it is too large
Load Diff
+15
-9
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package local
|
||||
|
||||
@@ -213,14 +213,20 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
|
||||
}
|
||||
}
|
||||
|
||||
// Set initialStakedFunds to the first validator key address
|
||||
// This address must exist in allocations with proper unlock schedule
|
||||
// The genesis package uses this to split staked funds among validators
|
||||
firstValidatorAddr, err := FormatAddress("P", hrp, validatorKeys[0].ShortID)
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("couldn't format first validator address: %w", err)
|
||||
// Set initialStakedFunds to the SECOND validator key address (not first).
|
||||
// The first key is kept OUT of initialStakedFunds so its allocation becomes
|
||||
// regular P-chain UTXOs, which are needed for wallet operations (chain creation, etc).
|
||||
// The second key's allocation will go to stakers for their stake weight.
|
||||
if len(validatorKeys) > 1 {
|
||||
secondValidatorAddr, err := FormatAddress("P", hrp, validatorKeys[1].ShortID)
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("couldn't format second validator address: %w", err)
|
||||
}
|
||||
genesis["initialStakedFunds"] = []string{secondValidatorAddr}
|
||||
} else {
|
||||
// Single node case: use empty initialStakedFunds
|
||||
genesis["initialStakedFunds"] = []string{}
|
||||
}
|
||||
genesis["initialStakedFunds"] = []string{firstValidatorAddr}
|
||||
|
||||
// Update start time to now
|
||||
genesis["startTime"] = uint64(now)
|
||||
@@ -247,7 +253,7 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
|
||||
IsBeacon: true,
|
||||
ChainConfigFiles: map[string]string{},
|
||||
UpgradeConfigFiles: map[string]string{},
|
||||
SubnetConfigFiles: map[string]string{},
|
||||
PChainConfigFiles: map[string]string{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -126,12 +126,12 @@ func writeFiles(networkID uint32, genesis []byte, nodeRootDir string, nodeConfig
|
||||
return nil, err
|
||||
}
|
||||
flags[config.ChainConfigDirKey] = chainConfigDir
|
||||
// subnet configs dir
|
||||
subnetConfigDir := filepath.Join(nodeRootDir, subnetConfigSubDir)
|
||||
if err := os.MkdirAll(subnetConfigDir, 0o750); err != nil {
|
||||
// P-chain configs dir
|
||||
pChainConfigDir := filepath.Join(nodeRootDir, pChainConfigSubDir)
|
||||
if err := os.MkdirAll(pChainConfigDir, 0o750); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
flags[config.NetConfigDirKey] = subnetConfigDir
|
||||
flags[config.NetConfigDirKey] = pChainConfigDir
|
||||
// chain configs
|
||||
for chainAlias, chainConfigFile := range nodeConfig.ChainConfigFiles {
|
||||
chainConfigPath := filepath.Join(chainConfigDir, chainAlias, configFileName)
|
||||
@@ -146,11 +146,11 @@ func writeFiles(networkID uint32, genesis []byte, nodeRootDir string, nodeConfig
|
||||
return nil, fmt.Errorf("couldn't write file at %q: %w", chainUpgradePath, err)
|
||||
}
|
||||
}
|
||||
// subnet configs
|
||||
for subnetID, subnetConfigFile := range nodeConfig.SubnetConfigFiles {
|
||||
subnetConfigPath := filepath.Join(subnetConfigDir, subnetID+".json")
|
||||
if err := createFileAndWrite(subnetConfigPath, []byte(subnetConfigFile)); err != nil {
|
||||
return nil, fmt.Errorf("couldn't write file at %q: %w", subnetConfigPath, err)
|
||||
// P-chain configs
|
||||
for chainID, pChainConfigFile := range nodeConfig.PChainConfigFiles {
|
||||
pChainConfigPath := filepath.Join(pChainConfigDir, chainID+".json")
|
||||
if err := createFileAndWrite(pChainConfigPath, []byte(pChainConfigFile)); err != nil {
|
||||
return nil, fmt.Errorf("couldn't write file at %q: %w", pChainConfigPath, err)
|
||||
}
|
||||
}
|
||||
return flags, nil
|
||||
|
||||
+37
-9
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package local
|
||||
|
||||
@@ -130,13 +130,24 @@ const (
|
||||
Jan1_2020 uint64 = 1577836800
|
||||
)
|
||||
|
||||
// GenerateVestingSchedule creates an unlock schedule with 1% per year for 100 years
|
||||
// starting from Jan 1, 2020. This means ~5-6% is already unlocked as of Dec 2025.
|
||||
// ImmediateUnlockLUX is 5% of 1B = 50M LUX for immediate spending (fees, transactions)
|
||||
const ImmediateUnlockLUX uint64 = OneBillionLUX * 5 / 100
|
||||
|
||||
// GenerateVestingSchedule creates an unlock schedule with:
|
||||
// - 5% immediately available (locktime=0) for transaction fees
|
||||
// - 1% per year for 95 years starting from Jan 1, 2020
|
||||
// This ensures the wallet has spendable funds for chain creation and other operations.
|
||||
func GenerateVestingSchedule() []map[string]interface{} {
|
||||
schedule := make([]map[string]interface{}, 100)
|
||||
for year := 0; year < 100; year++ {
|
||||
// First entry: immediately available funds (locktime=0)
|
||||
schedule := make([]map[string]interface{}, 96) // 1 immediate + 95 vested
|
||||
schedule[0] = map[string]interface{}{
|
||||
"amount": ImmediateUnlockLUX,
|
||||
"locktime": uint64(0), // Immediately available
|
||||
}
|
||||
// Remaining 95% vests 1% per year starting from 2020
|
||||
for year := 0; year < 95; year++ {
|
||||
unlockTime := Jan1_2020 + (uint64(year) * SecondsPerYear)
|
||||
schedule[year] = map[string]interface{}{
|
||||
schedule[year+1] = map[string]interface{}{
|
||||
"amount": OnePercentLUX,
|
||||
"locktime": unlockTime,
|
||||
}
|
||||
@@ -145,8 +156,9 @@ func GenerateVestingSchedule() []map[string]interface{} {
|
||||
}
|
||||
|
||||
// GenerateAllocationsFromKeys creates genesis allocations for loaded keys with vesting
|
||||
// The first key gets immediately spendable funds (locktime=0) for transaction fees.
|
||||
// Other keys get vesting schedules starting from Jan 1, 2020.
|
||||
func GenerateAllocationsFromKeys(keys []KeyInfo, hrp string) ([]map[string]interface{}, error) {
|
||||
vestingSchedule := GenerateVestingSchedule()
|
||||
allocations := make([]map[string]interface{}, len(keys))
|
||||
|
||||
for i, key := range keys {
|
||||
@@ -154,11 +166,27 @@ func GenerateAllocationsFromKeys(keys []KeyInfo, hrp string) ([]map[string]inter
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to format address for key %d: %w", i, err)
|
||||
}
|
||||
|
||||
var unlockSchedule []map[string]interface{}
|
||||
if i == 0 {
|
||||
// First key: all funds immediately available (locktime=0) for transactions
|
||||
// This matches how mainnet treasury works
|
||||
unlockSchedule = []map[string]interface{}{
|
||||
{
|
||||
"amount": OneBillionLUX,
|
||||
"locktime": uint64(0),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
// Other keys: use vesting schedule
|
||||
unlockSchedule = GenerateVestingSchedule()
|
||||
}
|
||||
|
||||
allocations[i] = map[string]interface{}{
|
||||
"ethAddr": key.EthAddr,
|
||||
"luxAddr": luxAddr,
|
||||
"initialAmount": OneBillionLUX, // 1B LUX on P-chain
|
||||
"unlockSchedule": vestingSchedule,
|
||||
"initialAmount": uint64(0), // initialAmount is NOT immediately spendable
|
||||
"unlockSchedule": unlockSchedule,
|
||||
}
|
||||
}
|
||||
return allocations, nil
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
//go:build mainnet
|
||||
// +build mainnet
|
||||
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package local_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/genesis/configs"
|
||||
"github.com/luxfi/netrunner/local"
|
||||
luxlog "github.com/luxfi/log"
|
||||
"github.com/luxfi/log/level"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
luxdBinaryPath = "/Users/z/go/bin/luxd"
|
||||
healthyTimeout = 3 * time.Minute
|
||||
mainnetNetworkID = uint32(96369)
|
||||
)
|
||||
|
||||
func TestMainnetConfigGeneration(t *testing.T) {
|
||||
// Test that we can generate a valid mainnet configuration
|
||||
netConfig, err := local.NewMainnetConfig(luxdBinaryPath, 5)
|
||||
require.NoError(t, err, "Failed to create mainnet config")
|
||||
|
||||
// Verify network ID in genesis
|
||||
var genesis map[string]interface{}
|
||||
err = json.Unmarshal([]byte(netConfig.Genesis), &genesis)
|
||||
require.NoError(t, err, "Failed to parse genesis JSON")
|
||||
|
||||
// Network ID should be mainnet (96369)
|
||||
networkIDFloat, ok := genesis["networkID"].(float64)
|
||||
require.True(t, ok, "networkID should be a number")
|
||||
require.Equal(t, mainnetNetworkID, uint32(networkIDFloat), "Expected mainnet network ID")
|
||||
|
||||
// Should have 5 node configs
|
||||
require.Len(t, netConfig.NodeConfigs, 5, "Expected 5 node configs")
|
||||
|
||||
// Each node should have staking keys configured
|
||||
for i, nodeConfig := range netConfig.NodeConfigs {
|
||||
require.NotEmpty(t, nodeConfig.StakingKey, "Node %d should have staking key", i)
|
||||
require.NotEmpty(t, nodeConfig.StakingCert, "Node %d should have staking cert", i)
|
||||
require.NotEmpty(t, nodeConfig.StakingSigningKey, "Node %d should have BLS signing key", i)
|
||||
}
|
||||
|
||||
// Should have initial stakers in genesis
|
||||
initialStakers, ok := genesis["initialStakers"].([]interface{})
|
||||
require.True(t, ok, "Genesis should have initialStakers")
|
||||
require.Len(t, initialStakers, 5, "Should have 5 initial stakers")
|
||||
|
||||
// Verify each staker has required fields
|
||||
for i, staker := range initialStakers {
|
||||
stakerMap, ok := staker.(map[string]interface{})
|
||||
require.True(t, ok, "Staker %d should be a map", i)
|
||||
require.NotEmpty(t, stakerMap["nodeID"], "Staker %d should have nodeID", i)
|
||||
require.NotEmpty(t, stakerMap["rewardAddress"], "Staker %d should have rewardAddress", i)
|
||||
require.NotNil(t, stakerMap["delegationFee"], "Staker %d should have delegationFee", i)
|
||||
require.NotNil(t, stakerMap["signer"], "Staker %d should have signer", i)
|
||||
}
|
||||
|
||||
t.Logf("Successfully generated mainnet config with %d nodes", len(netConfig.NodeConfigs))
|
||||
}
|
||||
|
||||
func TestMainnetGenesisFromConfigs(t *testing.T) {
|
||||
// Test loading genesis from configs package
|
||||
genesisData, err := configs.GetGenesis(mainnetNetworkID)
|
||||
require.NoError(t, err, "Failed to load mainnet genesis")
|
||||
require.NotEmpty(t, genesisData, "Genesis data should not be empty")
|
||||
|
||||
var genesis map[string]interface{}
|
||||
err = json.Unmarshal(genesisData, &genesis)
|
||||
require.NoError(t, err, "Failed to parse genesis JSON")
|
||||
|
||||
// Verify network ID
|
||||
networkIDFloat, ok := genesis["networkID"].(float64)
|
||||
require.True(t, ok, "networkID should be a number")
|
||||
require.Equal(t, mainnetNetworkID, uint32(networkIDFloat), "Expected mainnet network ID")
|
||||
|
||||
// Verify C-chain genesis
|
||||
cChainGenesis, ok := genesis["cChainGenesis"].(string)
|
||||
require.True(t, ok, "cChainGenesis should be a string")
|
||||
require.NotEmpty(t, cChainGenesis, "cChainGenesis should not be empty")
|
||||
|
||||
var cChain map[string]interface{}
|
||||
err = json.Unmarshal([]byte(cChainGenesis), &cChain)
|
||||
require.NoError(t, err, "Failed to parse cChainGenesis")
|
||||
|
||||
// Verify C-chain chainId matches network ID
|
||||
configObj, ok := cChain["config"].(map[string]interface{})
|
||||
require.True(t, ok, "cChain should have config")
|
||||
chainIDFloat, ok := configObj["chainId"].(float64)
|
||||
require.True(t, ok, "config should have chainId")
|
||||
require.Equal(t, mainnetNetworkID, uint32(chainIDFloat), "C-chain chainId should match network ID")
|
||||
|
||||
t.Logf("Mainnet genesis loaded successfully with network ID %d", uint32(networkIDFloat))
|
||||
}
|
||||
|
||||
func TestMainnetFiveNodeNetwork(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test in short mode")
|
||||
}
|
||||
|
||||
// Create logger
|
||||
logFactory := luxlog.NewFactoryWithConfig(luxlog.Config{
|
||||
DisplayLevel: level.Info,
|
||||
LogLevel: level.Debug,
|
||||
})
|
||||
log, err := logFactory.Make("test")
|
||||
require.NoError(t, err, "Failed to create logger")
|
||||
|
||||
// Create mainnet config for 5 nodes
|
||||
netConfig, err := local.NewMainnetConfig(luxdBinaryPath, 5)
|
||||
require.NoError(t, err, "Failed to create mainnet config")
|
||||
|
||||
// Create network
|
||||
nw, err := local.NewNetwork(log, netConfig, "", "", true)
|
||||
require.NoError(t, err, "Failed to create network")
|
||||
defer func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
_ = nw.Stop(ctx)
|
||||
}()
|
||||
|
||||
// Wait for network to be healthy
|
||||
ctx, cancel := context.WithTimeout(context.Background(), healthyTimeout)
|
||||
defer cancel()
|
||||
|
||||
t.Log("Waiting for network to become healthy...")
|
||||
err = nw.Healthy(ctx)
|
||||
require.NoError(t, err, "Network failed to become healthy")
|
||||
|
||||
// Get network info
|
||||
nodes, err := nw.GetAllNodes()
|
||||
require.NoError(t, err, "Failed to get nodes")
|
||||
require.Len(t, nodes, 5, "Should have 5 nodes")
|
||||
|
||||
t.Logf("Network healthy with %d nodes", len(nodes))
|
||||
|
||||
// Log node URIs
|
||||
for name, node := range nodes {
|
||||
t.Logf("Node %s: %s", name, node.GetURL())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMainnetConsensusValidation(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test in short mode")
|
||||
}
|
||||
|
||||
// Create logger
|
||||
logFactory := luxlog.NewFactoryWithConfig(luxlog.Config{
|
||||
DisplayLevel: level.Info,
|
||||
LogLevel: level.Debug,
|
||||
})
|
||||
log, err := logFactory.Make("test")
|
||||
require.NoError(t, err, "Failed to create logger")
|
||||
|
||||
// Create mainnet config for 5 nodes
|
||||
netConfig, err := local.NewMainnetConfig(luxdBinaryPath, 5)
|
||||
require.NoError(t, err, "Failed to create mainnet config")
|
||||
|
||||
// Create network
|
||||
nw, err := local.NewNetwork(log, netConfig, "", "", true)
|
||||
require.NoError(t, err, "Failed to create network")
|
||||
defer func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
_ = nw.Stop(ctx)
|
||||
}()
|
||||
|
||||
// Wait for network to be healthy
|
||||
ctx, cancel := context.WithTimeout(context.Background(), healthyTimeout)
|
||||
defer cancel()
|
||||
|
||||
t.Log("Waiting for network to become healthy...")
|
||||
err = nw.Healthy(ctx)
|
||||
require.NoError(t, err, "Network failed to become healthy")
|
||||
|
||||
// Verify each node is running with correct network ID
|
||||
nodes, err := nw.GetAllNodes()
|
||||
require.NoError(t, err, "Failed to get nodes")
|
||||
|
||||
for name, node := range nodes {
|
||||
// Get info from node
|
||||
client := node.GetAPIClient()
|
||||
require.NotNil(t, client, "Node %s should have API client", name)
|
||||
|
||||
info := client.InfoAPI()
|
||||
require.NotNil(t, info, "Node %s should have Info API", name)
|
||||
|
||||
// Get network ID from node
|
||||
nodeNetworkID, err := info.GetNetworkID(ctx)
|
||||
require.NoError(t, err, "Failed to get network ID from node %s", name)
|
||||
require.Equal(t, mainnetNetworkID, nodeNetworkID, "Node %s should have mainnet network ID", name)
|
||||
|
||||
t.Logf("Node %s: Network ID = %d", name, nodeNetworkID)
|
||||
}
|
||||
|
||||
t.Log("All nodes validated with correct mainnet configuration")
|
||||
}
|
||||
+29
-29
@@ -69,8 +69,8 @@ var (
|
||||
config.BootstrapIPsKey: {},
|
||||
config.BootstrapIDsKey: {},
|
||||
}
|
||||
chainConfigSubDir = "chainConfigs"
|
||||
subnetConfigSubDir = "subnetConfigs"
|
||||
chainConfigSubDir = "chainConfigs"
|
||||
pChainConfigSubDir = "pChainConfigs"
|
||||
|
||||
snapshotsRelPath = filepath.Join(".netrunner", "snapshots")
|
||||
|
||||
@@ -112,12 +112,12 @@ type localNetwork struct {
|
||||
chainConfigFiles map[string]string
|
||||
// upgrade config files to use per default
|
||||
upgradeConfigFiles map[string]string
|
||||
// subnet config files to use per default
|
||||
subnetConfigFiles map[string]string
|
||||
// P-chain config files to use per default
|
||||
pChainConfigFiles map[string]string
|
||||
// if true, for ports given in conf that are already taken, assign new random ones
|
||||
reassignPortsIfUsed bool
|
||||
// map from subnet id to elastic subnet tx id
|
||||
subnetID2ElasticSubnetID map[ids.ID]ids.ID
|
||||
// map from chain id to elastic chain tx id
|
||||
chainID2ElasticChainID map[ids.ID]ids.ID
|
||||
}
|
||||
|
||||
type deprecatedFlagEsp struct {
|
||||
@@ -215,7 +215,7 @@ func init() {
|
||||
"C": string(cChainConfig),
|
||||
},
|
||||
UpgradeConfigFiles: map[string]string{},
|
||||
SubnetConfigFiles: map[string]string{},
|
||||
PChainConfigFiles: map[string]string{},
|
||||
}
|
||||
|
||||
for i := 0; i < len(defaultNetworkConfig.NodeConfigs); i++ {
|
||||
@@ -330,7 +330,7 @@ func newNetwork(
|
||||
rootDir: rootDir,
|
||||
snapshotsDir: snapshotsDir,
|
||||
reassignPortsIfUsed: reassignPortsIfUsed,
|
||||
subnetID2ElasticSubnetID: map[ids.ID]ids.ID{},
|
||||
chainID2ElasticChainID: map[ids.ID]ids.ID{},
|
||||
}
|
||||
return net, nil
|
||||
}
|
||||
@@ -442,9 +442,9 @@ func (ln *localNetwork) loadConfig(ctx context.Context, networkConfig network.Co
|
||||
if ln.upgradeConfigFiles == nil {
|
||||
ln.upgradeConfigFiles = map[string]string{}
|
||||
}
|
||||
ln.subnetConfigFiles = networkConfig.SubnetConfigFiles
|
||||
if ln.subnetConfigFiles == nil {
|
||||
ln.subnetConfigFiles = map[string]string{}
|
||||
ln.chainConfigFiles = networkConfig.ChainConfigFiles
|
||||
if ln.chainConfigFiles == nil {
|
||||
ln.chainConfigFiles = map[string]string{}
|
||||
}
|
||||
|
||||
// Sort node configs so beacons start first
|
||||
@@ -496,8 +496,8 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) {
|
||||
if nodeConfig.UpgradeConfigFiles == nil {
|
||||
nodeConfig.UpgradeConfigFiles = map[string]string{}
|
||||
}
|
||||
if nodeConfig.SubnetConfigFiles == nil {
|
||||
nodeConfig.SubnetConfigFiles = map[string]string{}
|
||||
if nodeConfig.ChainConfigFiles == nil {
|
||||
nodeConfig.ChainConfigFiles = map[string]string{}
|
||||
}
|
||||
|
||||
// load node defaults
|
||||
@@ -516,10 +516,10 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) {
|
||||
nodeConfig.UpgradeConfigFiles[k] = v
|
||||
}
|
||||
}
|
||||
for k, v := range ln.subnetConfigFiles {
|
||||
_, ok := nodeConfig.SubnetConfigFiles[k]
|
||||
for k, v := range ln.chainConfigFiles {
|
||||
_, ok := nodeConfig.ChainConfigFiles[k]
|
||||
if !ok {
|
||||
nodeConfig.SubnetConfigFiles[k] = v
|
||||
nodeConfig.ChainConfigFiles[k] = v
|
||||
}
|
||||
}
|
||||
addNetworkFlags(ln.flags, nodeConfig.Flags)
|
||||
@@ -688,7 +688,7 @@ func (ln *localNetwork) healthy(ctx context.Context) error {
|
||||
if healthClient == nil {
|
||||
return fmt.Errorf("health client is nil for node %v", nodeName)
|
||||
}
|
||||
health, err := (*healthClient).Health(ctx, nil)
|
||||
health, err := healthClient.Health(ctx, nil)
|
||||
if err == nil && health.Healthy {
|
||||
ln.log.Debug("node became healthy", zap.String("name", nodeName))
|
||||
return nil
|
||||
@@ -893,16 +893,16 @@ func (ln *localNetwork) resumeNode(
|
||||
}
|
||||
|
||||
// Restart [nodeName] using the same config, optionally changing [binaryPath],
|
||||
// [pluginDir], [trackSubnets], [chainConfigs], [upgradeConfigs], [subnetConfigs]
|
||||
// [pluginDir], [trackChains], [chainConfigs], [upgradeConfigs], [pChainConfigs]
|
||||
func (ln *localNetwork) RestartNode(
|
||||
ctx context.Context,
|
||||
nodeName string,
|
||||
binaryPath string,
|
||||
pluginDir string,
|
||||
trackSubnets string,
|
||||
trackChains string,
|
||||
chainConfigs map[string]string,
|
||||
upgradeConfigs map[string]string,
|
||||
subnetConfigs map[string]string,
|
||||
pChainConfigs map[string]string,
|
||||
) error {
|
||||
ln.lock.Lock()
|
||||
defer ln.lock.Unlock()
|
||||
@@ -912,10 +912,10 @@ func (ln *localNetwork) RestartNode(
|
||||
nodeName,
|
||||
binaryPath,
|
||||
pluginDir,
|
||||
trackSubnets,
|
||||
trackChains,
|
||||
chainConfigs,
|
||||
upgradeConfigs,
|
||||
subnetConfigs,
|
||||
pChainConfigs,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -924,10 +924,10 @@ func (ln *localNetwork) restartNode(
|
||||
nodeName string,
|
||||
binaryPath string,
|
||||
pluginDir string,
|
||||
trackSubnets string,
|
||||
trackChains string,
|
||||
chainConfigs map[string]string,
|
||||
upgradeConfigs map[string]string,
|
||||
subnetConfigs map[string]string,
|
||||
pChainConfigs map[string]string,
|
||||
) error {
|
||||
node, ok := ln.nodes[nodeName]
|
||||
if !ok {
|
||||
@@ -943,8 +943,8 @@ func (ln *localNetwork) restartNode(
|
||||
nodeConfig.Flags[config.PluginDirKey] = pluginDir
|
||||
}
|
||||
|
||||
if trackSubnets != "" {
|
||||
nodeConfig.Flags[config.TrackNetsKey] = trackSubnets
|
||||
if trackChains != "" {
|
||||
nodeConfig.Flags[config.TrackNetsKey] = trackChains
|
||||
}
|
||||
|
||||
// keep same ports, dbdir in node flags
|
||||
@@ -961,9 +961,9 @@ func (ln *localNetwork) restartNode(
|
||||
for k, v := range upgradeConfigs {
|
||||
nodeConfig.UpgradeConfigFiles[k] = v
|
||||
}
|
||||
// apply subnet configs
|
||||
for k, v := range subnetConfigs {
|
||||
nodeConfig.SubnetConfigFiles[k] = v
|
||||
// apply chain configs
|
||||
for k, v := range chainConfigs {
|
||||
nodeConfig.ChainConfigFiles[k] = v
|
||||
}
|
||||
|
||||
if !node.paused {
|
||||
|
||||
+22
-22
@@ -144,7 +144,7 @@ func TestNewNetworkEmpty(t *testing.T) {
|
||||
networkConfig := testNetworkConfig(t)
|
||||
networkConfig.NodeConfigs = nil
|
||||
net, err := newNetwork(
|
||||
logging.NoLog{},
|
||||
luxlog.NoLog{},
|
||||
newMockAPISuccessful,
|
||||
&localTestProcessUndefNodeProcessCreator{},
|
||||
"",
|
||||
@@ -207,7 +207,7 @@ func TestNewNetworkOneNode(t *testing.T) {
|
||||
networkConfig.NodeConfigs = networkConfig.NodeConfigs[:1]
|
||||
creator := newLocalTestOneNodeCreator(require, networkConfig)
|
||||
net, err := newNetwork(
|
||||
logging.NoLog{},
|
||||
luxlog.NoLog{},
|
||||
newMockAPISuccessful,
|
||||
creator,
|
||||
"",
|
||||
@@ -235,7 +235,7 @@ func TestNewNetworkFailToStartNode(t *testing.T) {
|
||||
require := require.New(t)
|
||||
networkConfig := testNetworkConfig(t)
|
||||
net, err := newNetwork(
|
||||
logging.NoLog{},
|
||||
luxlog.NoLog{},
|
||||
newMockAPISuccessful,
|
||||
&localTestFailedStartProcessCreator{},
|
||||
"",
|
||||
@@ -477,7 +477,7 @@ func TestWrongNetworkConfigs(t *testing.T) {
|
||||
require := require.New(t)
|
||||
for name, tt := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), tt.config)
|
||||
require.Error(err)
|
||||
@@ -491,7 +491,7 @@ func TestUnhealthyNetwork(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
networkConfig := testNetworkConfig(t)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPIUnhealthy, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPIUnhealthy, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), networkConfig)
|
||||
require.NoError(err)
|
||||
@@ -506,7 +506,7 @@ func TestGeneratedNodesNames(t *testing.T) {
|
||||
for i := range networkConfig.NodeConfigs {
|
||||
networkConfig.NodeConfigs[i].Name = ""
|
||||
}
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), networkConfig)
|
||||
require.NoError(err)
|
||||
@@ -526,7 +526,7 @@ func TestGenerateDefaultNetwork(t *testing.T) {
|
||||
require := require.New(t)
|
||||
binaryPath := "pepito"
|
||||
networkConfig := NewDefaultConfig(binaryPath)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), networkConfig)
|
||||
require.NoError(err)
|
||||
@@ -576,7 +576,7 @@ func TestNetworkFromConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
networkConfig := testNetworkConfig(t)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), networkConfig)
|
||||
require.NoError(err)
|
||||
@@ -600,7 +600,7 @@ func TestNetworkNodeOps(t *testing.T) {
|
||||
// Start a new, empty network
|
||||
emptyNetworkConfig, err := emptyNetworkConfig()
|
||||
require.NoError(err)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), emptyNetworkConfig)
|
||||
require.NoError(err)
|
||||
@@ -638,7 +638,7 @@ func TestNodeNotFound(t *testing.T) {
|
||||
emptyNetworkConfig, err := emptyNetworkConfig()
|
||||
require.NoError(err)
|
||||
networkConfig := testNetworkConfig(t)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), emptyNetworkConfig)
|
||||
require.NoError(err)
|
||||
@@ -671,7 +671,7 @@ func TestStoppedNetwork(t *testing.T) {
|
||||
emptyNetworkConfig, err := emptyNetworkConfig()
|
||||
require.NoError(err)
|
||||
networkConfig := testNetworkConfig(t)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), emptyNetworkConfig)
|
||||
require.NoError(err)
|
||||
@@ -704,7 +704,7 @@ func TestStoppedNetwork(t *testing.T) {
|
||||
func TestGetAllNodes(t *testing.T) {
|
||||
require := require.New(t)
|
||||
networkConfig := testNetworkConfig(t)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), networkConfig)
|
||||
require.NoError(err)
|
||||
@@ -746,7 +746,7 @@ func TestFlags(t *testing.T) {
|
||||
}
|
||||
|
||||
nw, err := newNetwork(
|
||||
logging.NoLog{},
|
||||
luxlog.NoLog{},
|
||||
newMockAPISuccessful,
|
||||
&localTestFlagCheckProcessCreator{
|
||||
// after creating the network, one flag should have been overridden by the node configs
|
||||
@@ -775,7 +775,7 @@ func TestFlags(t *testing.T) {
|
||||
v.Flags = flags
|
||||
}
|
||||
nw, err = newNetwork(
|
||||
logging.NoLog{},
|
||||
luxlog.NoLog{},
|
||||
newMockAPISuccessful,
|
||||
&localTestFlagCheckProcessCreator{
|
||||
// after creating the network, only node configs should exist
|
||||
@@ -803,7 +803,7 @@ func TestFlags(t *testing.T) {
|
||||
v.Flags = nil
|
||||
}
|
||||
nw, err = newNetwork(
|
||||
logging.NoLog{},
|
||||
luxlog.NoLog{},
|
||||
newMockAPISuccessful,
|
||||
&localTestFlagCheckProcessCreator{
|
||||
// after creating the network, only flags from the network config should exist
|
||||
@@ -845,7 +845,7 @@ func TestChildCmdRedirection(t *testing.T) {
|
||||
writtenCh: make(chan struct{}),
|
||||
}
|
||||
npc := &nodeProcessCreator{
|
||||
log: logging.NoLog{},
|
||||
log: luxlog.NoLog{},
|
||||
stdout: buf,
|
||||
stderr: buf,
|
||||
colorPicker: utils.NewColorPicker(),
|
||||
@@ -895,7 +895,7 @@ 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(logging.Reset)
|
||||
expectedLen := len(expectedResult) + len(utils.NewColorPicker().NextColor()) + len(mockNodeName) + 3 + len(luxlog.Reset)
|
||||
if len(result) != expectedLen {
|
||||
t.Fatalf("expected string length to be %d, but it was %d", expectedLen, len(result))
|
||||
}
|
||||
@@ -923,9 +923,9 @@ func checkNetwork(t *testing.T, net network.Network, runningNodes map[string]str
|
||||
|
||||
// Return a network config that has no nodes
|
||||
func emptyNetworkConfig() (network.Config, error) {
|
||||
networkID := uint32(1337)
|
||||
networkID := uint32(12345) // Use a custom test network ID (not mainnet/testnet/local)
|
||||
// Use a dummy genesis
|
||||
genesis, err := network.NewLuxGenesis(
|
||||
genesis, err := network.NewGenesis(
|
||||
networkID,
|
||||
[]network.AddrAndBalance{
|
||||
{
|
||||
@@ -1158,7 +1158,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, subnetConfigSubDir)
|
||||
subnetConfigDir := filepath.Join(tmpDir, pChainConfigSubDir)
|
||||
cChainConfigPath := filepath.Join(tmpDir, chainConfigSubDir, "C", configFileName)
|
||||
|
||||
type test struct {
|
||||
@@ -1273,7 +1273,7 @@ func TestRemoveBeacon(t *testing.T) {
|
||||
// create a network with no nodes in it
|
||||
emptyNetworkConfig, err := emptyNetworkConfig()
|
||||
require.NoError(err)
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), emptyNetworkConfig)
|
||||
require.NoError(err)
|
||||
@@ -1324,7 +1324,7 @@ func TestHealthyDuringNetworkStop(t *testing.T) {
|
||||
require := require.New(t)
|
||||
networkConfig := testNetworkConfig(t)
|
||||
// Calls to a node's Healthy() function blocks until context cancelled
|
||||
net, err := newNetwork(logging.NoLog{}, newMockAPIHealthyBlocks, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
net, err := newNetwork(luxlog.NoLog{}, newMockAPIHealthyBlocks, &localTestSuccessfulNodeProcessCreator{}, "", "", false)
|
||||
require.NoError(err)
|
||||
err = net.loadConfig(context.Background(), networkConfig)
|
||||
require.NoError(err)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
//go:build integration
|
||||
// +build integration
|
||||
|
||||
package local
|
||||
|
||||
import (
|
||||
|
||||
+24
-24
@@ -24,26 +24,26 @@ import (
|
||||
|
||||
const (
|
||||
deprecatedBuildDirKey = "build-dir"
|
||||
deprecatedWhitelistedSubnetsKey = "whitelisted-subnets"
|
||||
deprecatedWhitelistedChainsKey = "whitelisted-chains"
|
||||
)
|
||||
|
||||
// NetworkState defines dynamic network information not available on blockchain db
|
||||
// NetworkState defines dynamic network information not available on chain db
|
||||
type NetworkState struct {
|
||||
// Map from subnet id to elastic subnet tx id
|
||||
SubnetID2ElasticSubnetID map[string]string `json:"subnetID2ElasticSubnetID"`
|
||||
// Map from chain id to elastic chain tx id
|
||||
ChainID2ElasticChainID map[string]string `json:"chainID2ElasticChainID"`
|
||||
}
|
||||
|
||||
// snapshots generated using older ANR versions may contain deprecated luxd flags
|
||||
func fixDeprecatedLuxdFlags(flags map[string]interface{}) error {
|
||||
if vIntf, ok := flags[deprecatedWhitelistedSubnetsKey]; ok {
|
||||
if vIntf, ok := flags[deprecatedWhitelistedChainsKey]; ok {
|
||||
v, ok := vIntf.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected %q to be of type string but got %T", deprecatedWhitelistedSubnetsKey, vIntf)
|
||||
return fmt.Errorf("expected %q to be of type string but got %T", deprecatedWhitelistedChainsKey, vIntf)
|
||||
}
|
||||
if v != "" {
|
||||
flags[config.TrackNetsKey] = v
|
||||
}
|
||||
delete(flags, deprecatedWhitelistedSubnetsKey)
|
||||
delete(flags, deprecatedWhitelistedChainsKey)
|
||||
}
|
||||
if vIntf, ok := flags[deprecatedBuildDirKey]; ok {
|
||||
v, ok := vIntf.(string)
|
||||
@@ -68,7 +68,7 @@ func NewNetworkFromSnapshot(
|
||||
pluginDir string,
|
||||
chainConfigs map[string]string,
|
||||
upgradeConfigs map[string]string,
|
||||
subnetConfigs map[string]string,
|
||||
pChainConfigs map[string]string,
|
||||
flags map[string]interface{},
|
||||
reassignPortsIfUsed bool,
|
||||
) (network.Network, error) {
|
||||
@@ -95,7 +95,7 @@ func NewNetworkFromSnapshot(
|
||||
pluginDir,
|
||||
chainConfigs,
|
||||
upgradeConfigs,
|
||||
subnetConfigs,
|
||||
pChainConfigs,
|
||||
flags,
|
||||
)
|
||||
return net, err
|
||||
@@ -182,7 +182,7 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) (
|
||||
BinaryPath: ln.binaryPath,
|
||||
ChainConfigFiles: ln.chainConfigFiles,
|
||||
UpgradeConfigFiles: ln.upgradeConfigFiles,
|
||||
SubnetConfigFiles: ln.subnetConfigFiles,
|
||||
PChainConfigFiles: ln.pChainConfigFiles,
|
||||
}
|
||||
|
||||
// no need to save this, will be generated automatically on snapshot load
|
||||
@@ -195,12 +195,12 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) (
|
||||
return "", err
|
||||
}
|
||||
// save dynamic part of network not available on blockchain
|
||||
subnetID2ElasticSubnetID := map[string]string{}
|
||||
for subnetID, elasticSubnetID := range ln.subnetID2ElasticSubnetID {
|
||||
subnetID2ElasticSubnetID[subnetID.String()] = elasticSubnetID.String()
|
||||
chainID2ElasticChainID := map[string]string{}
|
||||
for chainID, elasticChainID := range ln.chainID2ElasticChainID {
|
||||
chainID2ElasticChainID[chainID.String()] = elasticChainID.String()
|
||||
}
|
||||
networkState := NetworkState{
|
||||
SubnetID2ElasticSubnetID: subnetID2ElasticSubnetID,
|
||||
ChainID2ElasticChainID: chainID2ElasticChainID,
|
||||
}
|
||||
networkStateJSON, err := json.MarshalIndent(networkState, "", " ")
|
||||
if err != nil {
|
||||
@@ -220,7 +220,7 @@ func (ln *localNetwork) loadSnapshot(
|
||||
pluginDir string,
|
||||
chainConfigs map[string]string,
|
||||
upgradeConfigs map[string]string,
|
||||
subnetConfigs map[string]string,
|
||||
pChainConfigs map[string]string,
|
||||
flags map[string]interface{},
|
||||
) error {
|
||||
ln.lock.Lock()
|
||||
@@ -289,8 +289,8 @@ func (ln *localNetwork) loadSnapshot(
|
||||
if networkConfig.NodeConfigs[i].UpgradeConfigFiles == nil {
|
||||
networkConfig.NodeConfigs[i].UpgradeConfigFiles = map[string]string{}
|
||||
}
|
||||
if networkConfig.NodeConfigs[i].SubnetConfigFiles == nil {
|
||||
networkConfig.NodeConfigs[i].SubnetConfigFiles = map[string]string{}
|
||||
if networkConfig.NodeConfigs[i].ChainConfigFiles == nil {
|
||||
networkConfig.NodeConfigs[i].ChainConfigFiles = map[string]string{}
|
||||
}
|
||||
for k, v := range chainConfigs {
|
||||
networkConfig.NodeConfigs[i].ChainConfigFiles[k] = v
|
||||
@@ -298,8 +298,8 @@ func (ln *localNetwork) loadSnapshot(
|
||||
for k, v := range upgradeConfigs {
|
||||
networkConfig.NodeConfigs[i].UpgradeConfigFiles[k] = v
|
||||
}
|
||||
for k, v := range subnetConfigs {
|
||||
networkConfig.NodeConfigs[i].SubnetConfigFiles[k] = v
|
||||
for k, v := range chainConfigs {
|
||||
networkConfig.NodeConfigs[i].ChainConfigFiles[k] = v
|
||||
}
|
||||
}
|
||||
// load network state not available at blockchain db
|
||||
@@ -314,17 +314,17 @@ func (ln *localNetwork) loadSnapshot(
|
||||
if err := json.Unmarshal(networkStateJSON, &networkState); err != nil {
|
||||
return fmt.Errorf("failure unmarshaling network state from snapshot: %w", err)
|
||||
}
|
||||
ln.subnetID2ElasticSubnetID = map[ids.ID]ids.ID{}
|
||||
for subnetIDStr, elasticSubnetIDStr := range networkState.SubnetID2ElasticSubnetID {
|
||||
subnetID, err := ids.FromString(subnetIDStr)
|
||||
ln.chainID2ElasticChainID = map[ids.ID]ids.ID{}
|
||||
for chainIDStr, elasticChainIDStr := range networkState.ChainID2ElasticChainID {
|
||||
chainID, err := ids.FromString(chainIDStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
elasticSubnetID, err := ids.FromString(elasticSubnetIDStr)
|
||||
elasticChainID, err := ids.FromString(elasticChainIDStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ln.subnetID2ElasticSubnetID[subnetID] = elasticSubnetID
|
||||
ln.chainID2ElasticChainID[chainID] = elasticChainID
|
||||
}
|
||||
}
|
||||
return ln.loadConfig(ctx, networkConfig)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package local
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
+8
-8
@@ -19,7 +19,7 @@ type NetworkType string
|
||||
|
||||
const (
|
||||
NetworkTypePrimary NetworkType = "primary" // Mainnet or Testnet
|
||||
NetworkTypeSubnet NetworkType = "subnet" // L1/L2 subnets
|
||||
NetworkTypeChain NetworkType = "chain" // L1/L2 chains
|
||||
)
|
||||
|
||||
// NetworkConfig defines configuration for a single network
|
||||
@@ -27,7 +27,7 @@ type NetworkConfig struct {
|
||||
NetworkID uint32 `json:"networkID"`
|
||||
Name string `json:"name"`
|
||||
Type NetworkType `json:"type"`
|
||||
ParentID uint32 `json:"parentID,omitempty"` // For subnets
|
||||
ParentID uint32 `json:"parentID,omitempty"` // For chains
|
||||
HTTPPort int `json:"httpPort"`
|
||||
StakingPort int `json:"stakingPort"`
|
||||
DataDir string `json:"dataDir"`
|
||||
@@ -39,7 +39,7 @@ type NetworkConfig struct {
|
||||
type ChainConfig struct {
|
||||
ChainID string `json:"chainID"`
|
||||
VMID string `json:"vmID"`
|
||||
SubnetID string `json:"subnetID,omitempty"`
|
||||
PChainID string `json:"pChainID,omitempty"`
|
||||
Genesis []byte `json:"genesis,omitempty"`
|
||||
IsEVM bool `json:"isEVM"`
|
||||
}
|
||||
@@ -73,14 +73,14 @@ type NetworkInstance struct {
|
||||
Config NetworkConfig
|
||||
Network network.Network
|
||||
Status NetworkStatus
|
||||
Subnets map[string]*SubnetInstance
|
||||
Chains map[string]*ChainInstance
|
||||
StartTime time.Time
|
||||
}
|
||||
|
||||
// SubnetInstance represents a running subnet
|
||||
type SubnetInstance struct {
|
||||
SubnetID string
|
||||
// ChainInstance represents a running chain
|
||||
type ChainInstance struct {
|
||||
ChainID string
|
||||
PChainID string
|
||||
ParentNetID uint32
|
||||
Validators []ids.NodeID
|
||||
Status NetworkStatus
|
||||
@@ -197,7 +197,7 @@ func (m *MultiNetworkManager) AddNetwork(config NetworkConfig) error {
|
||||
instance := &NetworkInstance{
|
||||
Config: config,
|
||||
Status: NetworkStatusStopped,
|
||||
Subnets: make(map[string]*SubnetInstance),
|
||||
Chains: make(map[string]*ChainInstance),
|
||||
}
|
||||
|
||||
m.networks[config.NetworkID] = instance
|
||||
|
||||
+37
-15
@@ -8,11 +8,12 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/netrunner/network/node"
|
||||
"github.com/luxfi/netrunner/utils"
|
||||
"github.com/luxfi/constants"
|
||||
"github.com/luxfi/genesis/pkg/genesis"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/constants"
|
||||
"github.com/luxfi/netrunner/network/node"
|
||||
"github.com/luxfi/netrunner/utils"
|
||||
"github.com/luxfi/node/utils/formatting/address"
|
||||
"github.com/luxfi/units"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
@@ -72,8 +73,8 @@ type Config struct {
|
||||
ChainConfigFiles map[string]string `json:"chainConfigFiles"`
|
||||
// Upgrade config files to use per default, if not specified in node config
|
||||
UpgradeConfigFiles map[string]string `json:"upgradeConfigFiles"`
|
||||
// Subnet config files to use per default, if not specified in node config
|
||||
SubnetConfigFiles map[string]string `json:"subnetConfigFiles"`
|
||||
// P-Chain config files to use per default, if not specified in node config
|
||||
PChainConfigFiles map[string]string `json:"pChainConfigFiles"`
|
||||
}
|
||||
|
||||
// Validate returns an error if this config is invalid
|
||||
@@ -108,13 +109,13 @@ func (c *Config) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return a genesis JSON where:
|
||||
// NewGenesis returns a genesis JSON where:
|
||||
// The nodes in [genesisVdrs] are validators.
|
||||
// The C-Chain and X-Chain balances are given by
|
||||
// [cChainBalances] and [xChainBalances].
|
||||
// Note that many of the genesis fields (i.e. reward addresses)
|
||||
// are randomly generated or hard-coded.
|
||||
func NewLuxGenesis(
|
||||
func NewGenesis(
|
||||
networkID uint32,
|
||||
xChainBalances []AddrAndBalance,
|
||||
cChainBalances []AddrAndBalance,
|
||||
@@ -133,12 +134,23 @@ func NewLuxGenesis(
|
||||
|
||||
// Address that controls stake doesn't matter -- generate it randomly
|
||||
genesisVdrStakeShortID := ids.GenerateTestShortID()
|
||||
|
||||
// Get the HRP for address formatting (custom for test networks)
|
||||
hrp := constants.GetHRP(networkID)
|
||||
|
||||
// Format addresses as strings for the JSON config
|
||||
zeroEthAddr := fmt.Sprintf("0x%s", ids.ShortID{}.Hex())
|
||||
genesisVdrStakeAddr, err := address.Format("P", hrp, genesisVdrStakeShortID[:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to format genesis validator stake address: %w", err)
|
||||
}
|
||||
|
||||
config := genesis.UnparsedConfig{
|
||||
NetworkID: networkID,
|
||||
Allocations: []genesis.UnparsedAllocation{
|
||||
{
|
||||
ETHAddr: ids.ShortID{}, // Zero address
|
||||
LUXAddr: genesisVdrStakeShortID,
|
||||
ETHAddr: zeroEthAddr, // Zero address as hex string
|
||||
LUXAddr: genesisVdrStakeAddr, // Bech32 formatted address
|
||||
InitialAmount: 0,
|
||||
UnlockSchedule: []genesis.LockedAmount{ // Provides stake to validators
|
||||
{
|
||||
@@ -148,22 +160,27 @@ func NewLuxGenesis(
|
||||
},
|
||||
},
|
||||
StartTime: uint64(time.Now().Unix()),
|
||||
InitialStakedFunds: []ids.ShortID{genesisVdrStakeShortID},
|
||||
InitialStakedFunds: []string{genesisVdrStakeAddr},
|
||||
InitialStakeDuration: 31_536_000, // 1 year
|
||||
InitialStakeDurationOffset: 5_400, // 90 minutes
|
||||
Message: "hello world",
|
||||
}
|
||||
|
||||
for _, xChainBal := range xChainBalances {
|
||||
// Format the LUX address as bech32 string
|
||||
luxAddr, err := address.Format("P", hrp, xChainBal.Addr[:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to format X-chain balance address: %w", err)
|
||||
}
|
||||
config.Allocations = append(
|
||||
config.Allocations,
|
||||
genesis.UnparsedAllocation{
|
||||
ETHAddr: ids.ShortID{}, // Zero address
|
||||
LUXAddr: xChainBal.Addr,
|
||||
ETHAddr: zeroEthAddr, // Zero address as hex string
|
||||
LUXAddr: luxAddr, // Bech32 formatted address
|
||||
InitialAmount: xChainBal.Balance.Uint64(),
|
||||
UnlockSchedule: []genesis.LockedAmount{
|
||||
{
|
||||
Amount: 100 * units.MegaLux, // Unlocked P-Chain balance for subnet deployment
|
||||
Amount: 100 * units.MegaLux, // Unlocked P-Chain balance for chain deployment
|
||||
Locktime: 0, // Locktime 0 = immediately available
|
||||
},
|
||||
{
|
||||
@@ -193,12 +210,17 @@ func NewLuxGenesis(
|
||||
// Set initial validators.
|
||||
// Give staking rewards to random address.
|
||||
rewardShortID := ids.GenerateTestShortID()
|
||||
rewardAddr, err := address.Format("P", hrp, rewardShortID[:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to format reward address: %w", err)
|
||||
}
|
||||
|
||||
for _, genesisVdr := range genesisVdrs {
|
||||
config.InitialStakers = append(
|
||||
config.InitialStakers,
|
||||
genesis.UnparsedStaker{
|
||||
NodeID: genesisVdr,
|
||||
RewardAddress: rewardShortID,
|
||||
NodeID: genesisVdr.String(), // NodeID as string
|
||||
RewardAddress: rewardAddr, // Bech32 formatted address
|
||||
DelegationFee: 10_000,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
{
|
||||
"networkID": 1337,
|
||||
"allocations": [
|
||||
{
|
||||
"ethAddr": "0xb3d82b1367d362de99ab59a658165aff520cbd4d",
|
||||
"luxAddr": "X-custom1g65uqn6t77p656w64023nh8nd9updzmxwd59gh",
|
||||
"initialAmount": 0,
|
||||
"luxAddr": "X-custom1g65uqn6t77p656w64023nh8nd9updzmxwd59gh",
|
||||
"unlockSchedule": [
|
||||
{
|
||||
"amount": 10000000000000000,
|
||||
@@ -14,8 +13,8 @@
|
||||
},
|
||||
{
|
||||
"ethAddr": "0xb3d82b1367d362de99ab59a658165aff520cbd4d",
|
||||
"luxAddr": "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
|
||||
"initialAmount": 300000000000000000,
|
||||
"luxAddr": "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
|
||||
"unlockSchedule": [
|
||||
{
|
||||
"amount": 20000000000000000
|
||||
@@ -28,8 +27,8 @@
|
||||
},
|
||||
{
|
||||
"ethAddr": "0xb3d82b1367d362de99ab59a658165aff520cbd4d",
|
||||
"luxAddr": "X-custom16045mxr3s2cjycqe2xfluk304xv3ezhkhsvkpr",
|
||||
"initialAmount": 10000000000000000,
|
||||
"luxAddr": "X-custom16045mxr3s2cjycqe2xfluk304xv3ezhkhsvkpr",
|
||||
"unlockSchedule": [
|
||||
{
|
||||
"amount": 10000000000000000,
|
||||
@@ -38,7 +37,7 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"startTime": 1630987200,
|
||||
"cChainGenesis": "{\"config\":{\"chainId\":43112,\"homesteadBlock\":0,\"daoForkBlock\":0,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"apricotPhase1BlockTimestamp\":0,\"apricotPhase2BlockTimestamp\":0},\"nonce\":\"0x0\",\"timestamp\":\"0x0\",\"extraData\":\"0x00\",\"gasLimit\":\"0x5f5e100\",\"difficulty\":\"0x0\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"coinbase\":\"0x0000000000000000000000000000000000000000\",\"alloc\":{\"8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC\":{\"balance\":\"0x295BE96E64066972000000\"}},\"number\":\"0x0\",\"gasUsed\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\"}",
|
||||
"initialStakeDuration": 31536000,
|
||||
"initialStakeDurationOffset": 5400,
|
||||
"initialStakedFunds": [
|
||||
@@ -46,31 +45,52 @@
|
||||
],
|
||||
"initialStakers": [
|
||||
{
|
||||
"delegationFee": 1000000,
|
||||
"nodeID": "NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg",
|
||||
"rewardAddress": "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
|
||||
"delegationFee": 1000000
|
||||
"signer": {
|
||||
"proofOfPossession": "0xa2569a137e65d3a507c4f1f7ffac74ec05916ba44dfbbb84d42c2736a2bc1e8be14038d3aeeeac7c78e19ecdde69d830051959f22559641a3f9e42377d7f64580acdc383c5c9e22f7f1114712a543c6997d6dc59c88555423497d9fff41fa79a",
|
||||
"publicKey": "0xb3ebbe748a1f06d19ee25d4e345ba8d6b5a426498a140c2519b518e3e6224abd7895075892f361acf24c10af968bc7de"
|
||||
}
|
||||
},
|
||||
{
|
||||
"delegationFee": 500000,
|
||||
"nodeID": "NodeID-MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ",
|
||||
"rewardAddress": "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
|
||||
"delegationFee": 500000
|
||||
"signer": {
|
||||
"proofOfPossession": "0xaf92674c3615d462527675da121b06023b116ddebc6e163919e562ab7cbe6adf20515cd2fc17c3e2d2d59953f285229e15f04302187bef5a4aa3ebdea1d18bf34047be654dd12491e882fb90b17b3cbde99ad43fc5cd0c26828bbe49a4b9456c",
|
||||
"publicKey": "0x8b49c4259529a801cc961c72248773b550379ff718a49f4ccc0e1f2ac338fe204432329aa1712f408f97eee12b22dd05"
|
||||
}
|
||||
},
|
||||
{
|
||||
"delegationFee": 250000,
|
||||
"nodeID": "NodeID-NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN",
|
||||
"rewardAddress": "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
|
||||
"delegationFee": 250000
|
||||
"signer": {
|
||||
"proofOfPossession": "0xa113145564d7ac540fade2526938fbd33233957901111328c86c4cbe7ed25f678173d95c54b3342fd7b723c3ed813f2b04fecf4a317205ce65638bb34bb58bb6746e74c63e6cbe5cb25c103b290ed270146b756d3901c8b0f99d083a44572c79",
|
||||
"publicKey": "0xb20ab07ea5cf8b77ab50f2071a6f1d2aab693c8bd89761430cd29de9fa0dbae83a32c7697d59ff1b06995b1596c16fa6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"delegationFee": 125000,
|
||||
"nodeID": "NodeID-GWPcbFJZFfZreETSoWjPimr846mXEKCtu",
|
||||
"rewardAddress": "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
|
||||
"delegationFee": 125000
|
||||
"signer": {
|
||||
"proofOfPossession": "0x8880500af123806295355eadbb36084619de729e2c4ac057f73784eb806ae19b4738550617fa8d6820cf1a352e19af6d042e140b3c967b8573e063c1e5aabce50dc2156e9caa6428b58e06a3624ac8170793ff4b4095397c1c981fbb2383dae6",
|
||||
"publicKey": "0xb43f74196c2b9e9980f815a99288ef76166b42e93663dcbce3526f9652cdb58b31a3d68798b08fb9806024620ca1d6cd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"delegationFee": 62500,
|
||||
"nodeID": "NodeID-P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5",
|
||||
"rewardAddress": "X-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p",
|
||||
"delegationFee": 62500
|
||||
"signer": {
|
||||
"proofOfPossession": "0x8e01fe13a6fa3ca5be4f78230b0d03ffff4741f186ddebf9a04819e8011eb9c1b81debad2e52a35ec89f4dfc517884b9075e46968d6c735f17cca3ab5c07a2cdc181233fcd8e9260d9fa7edc12572dff13972c9b3233f34258fb34d9e6b732ba",
|
||||
"publicKey": "0xa37e938a8e1fb71286ae1a9dc81585bae5c63d8cae3b95160ce9acce621c8ee64afa0491a2c757ba24d8be2da1052090"
|
||||
}
|
||||
}
|
||||
],
|
||||
"cChainGenesis": "{\"config\":{\"chainId\":43112,\"homesteadBlock\":0,\"daoForkBlock\":0,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"apricotPhase1BlockTimestamp\":0,\"apricotPhase2BlockTimestamp\":0},\"nonce\":\"0x0\",\"timestamp\":\"0x0\",\"extraData\":\"0x00\",\"gasLimit\":\"0x5f5e100\",\"difficulty\":\"0x0\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"coinbase\":\"0x0000000000000000000000000000000000000000\",\"alloc\":{\"8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC\":{\"balance\":\"0x295BE96E64066972000000\"}},\"number\":\"0x0\",\"gasUsed\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\"}",
|
||||
"message": "{{ fun_quote }}"
|
||||
"message": "{{ fun_quote }}",
|
||||
"networkID": 1337,
|
||||
"startTime": 1630987200
|
||||
}
|
||||
+25
-24
@@ -16,7 +16,7 @@ var (
|
||||
)
|
||||
|
||||
type PermissionlessValidatorSpec struct {
|
||||
SubnetID string
|
||||
ChainID string
|
||||
AssetID string
|
||||
NodeName string
|
||||
StakedAmount uint64
|
||||
@@ -24,8 +24,8 @@ type PermissionlessValidatorSpec struct {
|
||||
StakeDuration time.Duration
|
||||
}
|
||||
|
||||
type ElasticSubnetSpec struct {
|
||||
SubnetID *string
|
||||
type ElasticChainSpec struct {
|
||||
ChainID *string
|
||||
AssetName string
|
||||
AssetSymbol string
|
||||
InitialSupply uint64
|
||||
@@ -42,25 +42,26 @@ type ElasticSubnetSpec struct {
|
||||
UptimeRequirement uint32
|
||||
}
|
||||
|
||||
type SubnetSpec struct {
|
||||
type ParticipantsSpec struct {
|
||||
Participants []string
|
||||
SubnetConfig []byte
|
||||
ChainConfig []byte
|
||||
}
|
||||
|
||||
type RemoveSubnetValidatorSpec struct {
|
||||
type RemoveChainValidatorSpec struct {
|
||||
NodeNames []string
|
||||
SubnetID string
|
||||
ChainID string
|
||||
}
|
||||
|
||||
type BlockchainSpec struct {
|
||||
type ChainSpec struct {
|
||||
VMName string
|
||||
Genesis []byte
|
||||
SubnetID *string
|
||||
SubnetSpec *SubnetSpec
|
||||
ChainID *string
|
||||
ParticipantsSpec *ParticipantsSpec
|
||||
ChainConfig []byte
|
||||
NetworkUpgrade []byte
|
||||
BlockchainAlias string
|
||||
Alias string
|
||||
PerNodeChainConfig map[string][]byte
|
||||
BlockchainName string // Unique name for the blockchain (defaults to VMName if empty)
|
||||
}
|
||||
|
||||
// Network is an abstraction of an Lux network
|
||||
@@ -103,19 +104,19 @@ type Network interface {
|
||||
// Get name of available snapshots
|
||||
GetSnapshotNames() ([]string, error)
|
||||
// Restart a given node using the same config, optionally changing binary path, plugin dir,
|
||||
// track subnets, a map of chain configs, a map of upgrade configs, and
|
||||
// a map of subnet configs
|
||||
// track chains, a map of chain configs, a map of upgrade configs, and
|
||||
// a map of chain configs
|
||||
RestartNode(context.Context, string, string, string, string, map[string]string, map[string]string, map[string]string) error
|
||||
// Create the specified blockchains
|
||||
CreateBlockchains(context.Context, []BlockchainSpec) ([]ids.ID, error)
|
||||
// Create the given numbers of subnets
|
||||
CreateSubnets(context.Context, []SubnetSpec) ([]ids.ID, error)
|
||||
// Transform subnet into elastic subnet
|
||||
TransformSubnet(context.Context, []ElasticSubnetSpec) ([]ids.ID, []ids.ID, error)
|
||||
// Add a validator into an elastic subnet
|
||||
// Create the specified chains
|
||||
CreateChains(context.Context, []ChainSpec) ([]ids.ID, error)
|
||||
// Create chain participant groups (validators)
|
||||
CreateParticipantGroups(context.Context, []ParticipantsSpec) ([]ids.ID, error)
|
||||
// Transform chain into elastic chain
|
||||
TransformChain(context.Context, []ElasticChainSpec) ([]ids.ID, []ids.ID, error)
|
||||
// Add a validator into an elastic chain
|
||||
AddPermissionlessValidators(context.Context, []PermissionlessValidatorSpec) error
|
||||
// Remove a validator from a subnet
|
||||
RemoveSubnetValidators(context.Context, []RemoveSubnetValidatorSpec) error
|
||||
// Get the elastic subnet tx id for the given subnet id
|
||||
GetElasticSubnetID(context.Context, ids.ID) (ids.ID, error)
|
||||
// Remove a validator from a chain
|
||||
RemoveChainValidators(context.Context, []RemoveChainValidatorSpec) error
|
||||
// Get the elastic chain tx id for the given chain id
|
||||
GetElasticChainID(context.Context, ids.ID) (ids.ID, error)
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ type Config struct {
|
||||
ChainConfigFiles map[string]string `json:"chainConfigFiles"`
|
||||
// May be nil.
|
||||
UpgradeConfigFiles map[string]string `json:"upgradeConfigFiles"`
|
||||
// May be nil.
|
||||
SubnetConfigFiles map[string]string `json:"subnetConfigFiles"`
|
||||
// May be nil. P-Chain chain (formerly subnet) config files.
|
||||
PChainConfigFiles map[string]string `json:"pChainConfigFiles"`
|
||||
// Flags can hold additional flags for the node.
|
||||
// It can be empty.
|
||||
// The precedence of flags handling is:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package orchestrator
|
||||
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
//go:build integration
|
||||
// +build integration
|
||||
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package orchestrator_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/netrunner/engines"
|
||||
_ "github.com/luxfi/netrunner/engines/lux" // Register lux engine
|
||||
"github.com/luxfi/netrunner/orchestrator"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -17,13 +22,17 @@ func TestMultiEngineOrchestration(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
// Skip if luxd binary is not available
|
||||
if _, err := exec.LookPath("luxd"); err != nil {
|
||||
t.Skip("luxd binary not found, skipping integration test")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
host := orchestrator.NewHost()
|
||||
|
||||
// Test starting Lux engine
|
||||
t.Run("StartLuxEngine", func(t *testing.T) {
|
||||
config := &engines.NodeConfig{
|
||||
options := &orchestrator.EngineOptions{
|
||||
NetworkID: 96369,
|
||||
HTTPPort: 19630,
|
||||
StakingPort: 19631,
|
||||
@@ -35,7 +44,7 @@ func TestMultiEngineOrchestration(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := host.StartEngine(ctx, "test-lux", engines.EngineLux, config)
|
||||
err := host.StartEngine(ctx, "test-lux", string(engines.EngineLux), options)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Wait for health
|
||||
@@ -55,23 +64,23 @@ func TestMultiEngineOrchestration(t *testing.T) {
|
||||
// Test starting multiple engines
|
||||
t.Run("MultipleEngines", func(t *testing.T) {
|
||||
// Start Lux
|
||||
luxConfig := &engines.NodeConfig{
|
||||
luxOptions := &orchestrator.EngineOptions{
|
||||
NetworkID: 96369,
|
||||
HTTPPort: 19640,
|
||||
StakingPort: 19641,
|
||||
LogLevel: "info",
|
||||
}
|
||||
err := host.StartEngine(ctx, "lux-1", engines.EngineLux, luxConfig)
|
||||
err := host.StartEngine(ctx, "lux-1", string(engines.EngineLux), luxOptions)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Start Lux
|
||||
avaConfig := &engines.NodeConfig{
|
||||
avaOptions := &orchestrator.EngineOptions{
|
||||
NetworkID: 43114,
|
||||
HTTPPort: 19650,
|
||||
StakingPort: 19651,
|
||||
LogLevel: "info",
|
||||
}
|
||||
err = host.StartEngine(ctx, "ava-1", engines.EngineLux, avaConfig)
|
||||
err = host.StartEngine(ctx, "ava-1", string(engines.EngineLux), avaOptions)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check both are running
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package orchestrator
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package orchestrator
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package orchestrator
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package orchestrator
|
||||
|
||||
|
||||
+1070
-2427
File diff suppressed because it is too large
Load Diff
+509
-968
File diff suppressed because it is too large
Load Diff
+62
-62
@@ -43,9 +43,9 @@ service ControlService {
|
||||
};
|
||||
}
|
||||
|
||||
rpc TransformElasticSubnets(TransformElasticSubnetsRequest) returns (TransformElasticSubnetsResponse) {
|
||||
rpc TransformElasticChains(TransformElasticChainsRequest) returns (TransformElasticChainsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/control/transformelasticsubnets"
|
||||
post: "/v1/control/transformelasticchains"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
@@ -57,16 +57,16 @@ service ControlService {
|
||||
};
|
||||
}
|
||||
|
||||
rpc RemoveSubnetValidator(RemoveSubnetValidatorRequest) returns (RemoveSubnetValidatorResponse) {
|
||||
rpc RemoveChainValidator(RemoveChainValidatorRequest) returns (RemoveChainValidatorResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/control/removesubnetvalidator"
|
||||
post: "/v1/control/removechainvalidator"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc CreateSubnets(CreateSubnetsRequest) returns (CreateSubnetsResponse) {
|
||||
rpc CreateChains(CreateChainsRequest) returns (CreateChainsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/control/createsubnets"
|
||||
post: "/v1/control/createchains"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
@@ -191,7 +191,7 @@ service ControlService {
|
||||
}
|
||||
}
|
||||
|
||||
message SubnetParticipants {
|
||||
message ChainParticipants {
|
||||
repeated string node_names = 1;
|
||||
}
|
||||
|
||||
@@ -209,18 +209,18 @@ message ClusterInfo {
|
||||
bool custom_chains_healthy = 7;
|
||||
// The map of blockchain IDs in "ids.ID" format to its blockchain information.
|
||||
map<string, CustomChainInfo> custom_chains = 8;
|
||||
map<string, SubnetInfo> subnets = 9;
|
||||
map<string, ChainInfo> chains = 9;
|
||||
}
|
||||
|
||||
message SubnetInfo {
|
||||
// If Subnet is an Elastic Subnet
|
||||
message ChainInfo {
|
||||
// If Chain is an Elastic Chain
|
||||
bool is_elastic = 1;
|
||||
|
||||
// TXID for the elastic subnet transform
|
||||
string elastic_subnet_id = 2;
|
||||
// TXID for the elastic chain transform
|
||||
string elastic_chain_id = 2;
|
||||
|
||||
// node validators of subnet
|
||||
SubnetParticipants subnet_participants = 3;
|
||||
// node validators of chain
|
||||
ChainParticipants chain_participants = 3;
|
||||
}
|
||||
|
||||
message CustomChainInfo {
|
||||
@@ -232,13 +232,13 @@ message CustomChainInfo {
|
||||
// VM ID in "ids.ID" format.
|
||||
string vm_id = 2;
|
||||
|
||||
// Create subnet transaction ID -- subnet ID.
|
||||
// The subnet ID must be whitelisted by the lux node.
|
||||
string subnet_id = 3;
|
||||
// Create chain transaction ID -- P-Chain chain ID.
|
||||
// The chain ID must be whitelisted by the lux node.
|
||||
string pchain_id = 3;
|
||||
|
||||
// Create blockchain transaction ID -- blockchain ID>
|
||||
// The blockchain ID is used for RPC endpoints.
|
||||
string chain_id = 4;
|
||||
string blockchain_id = 4;
|
||||
}
|
||||
|
||||
message NodeInfo {
|
||||
@@ -249,7 +249,7 @@ message NodeInfo {
|
||||
string log_dir = 5;
|
||||
string db_dir = 6;
|
||||
string plugin_dir = 7;
|
||||
string whitelisted_subnets = 8;
|
||||
string whitelisted_chains = 8;
|
||||
bytes config = 9;
|
||||
bool paused = 10;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ message ListOfAttachedPeerInfo {
|
||||
message StartRequest {
|
||||
string exec_path = 1;
|
||||
optional uint32 num_nodes = 2;
|
||||
optional string whitelisted_subnets = 3;
|
||||
optional string whitelisted_chains = 3;
|
||||
optional string global_node_config = 4;
|
||||
// Used for both database and log files.
|
||||
optional string root_data_dir = 5;
|
||||
@@ -276,19 +276,19 @@ message StartRequest {
|
||||
// The list of:
|
||||
// - custom chain's VM name
|
||||
// - genesis file path
|
||||
// - (optional) subnet id to use.
|
||||
// - (optional) chain id to use.
|
||||
// - chain config file path
|
||||
// - network upgrade file path
|
||||
//
|
||||
// subnet id must be always nil when using StartRequest, as the network is empty and has no preloaded
|
||||
// subnet ids available.
|
||||
// chain id must be always nil when using StartRequest, as the network is empty and has no preloaded
|
||||
// chain ids available.
|
||||
//
|
||||
// The matching file with the name in "ids.ID" format must exist.
|
||||
// e.g., ids.ToID(hashing.ComputeHash256("subnetevm")).String()
|
||||
// e.g., subnet-cli create VMID subnetevm
|
||||
// e.g., ids.ToID(hashing.ComputeHash256("chainevm")).String()
|
||||
// e.g., chain-cli create VMID chainevm
|
||||
//
|
||||
// If this field is set to none (by default), the node/network-runner
|
||||
// does not install the custom chain and does not create the subnet,
|
||||
// does not install the custom chain and does not create the chain,
|
||||
// even if the VM binary exists on the local plugins directory.
|
||||
repeated BlockchainSpec blockchain_specs = 7;
|
||||
|
||||
@@ -310,10 +310,10 @@ message StartRequest {
|
||||
// use dynamic ports instead of default ones
|
||||
optional bool dynamic_ports = 12;
|
||||
|
||||
// Map of subnet id to subnet config file contents.
|
||||
// If specified, will create a file "subnetid.json" under subnets config dir with
|
||||
// Map of chain id to chain config file contents.
|
||||
// If specified, will create a file "chainid.json" under chains config dir with
|
||||
// the contents provided here.
|
||||
map<string, string> subnet_configs = 13;
|
||||
map<string, string> chain_config_files = 13;
|
||||
}
|
||||
|
||||
message RPCVersionRequest {}
|
||||
@@ -327,15 +327,15 @@ message StartResponse {
|
||||
repeated string chain_ids = 2;
|
||||
}
|
||||
|
||||
message SubnetSpec {
|
||||
message ChainSpec {
|
||||
// if empty, assumes all nodes should be participants
|
||||
repeated string participants = 1;
|
||||
// either file path or file contents
|
||||
string subnet_config = 2;
|
||||
string chain_config_file = 2;
|
||||
}
|
||||
|
||||
message ElasticSubnetSpec {
|
||||
string subnet_id = 1;
|
||||
message ElasticChainSpec {
|
||||
string chain_id = 1;
|
||||
string asset_name = 2;
|
||||
string asset_symbol = 3;
|
||||
uint64 initial_supply = 4;
|
||||
@@ -352,18 +352,18 @@ message ElasticSubnetSpec {
|
||||
uint32 uptime_requirement = 15;
|
||||
}
|
||||
|
||||
message TransformElasticSubnetsRequest {
|
||||
repeated ElasticSubnetSpec elastic_subnet_spec = 1;
|
||||
message TransformElasticChainsRequest {
|
||||
repeated ElasticChainSpec elastic_chain_spec = 1;
|
||||
}
|
||||
|
||||
message TransformElasticSubnetsResponse {
|
||||
message TransformElasticChainsResponse {
|
||||
ClusterInfo cluster_info = 1;
|
||||
repeated string tx_ids = 2;
|
||||
repeated string asset_ids = 3;
|
||||
}
|
||||
|
||||
message PermissionlessValidatorSpec {
|
||||
string subnet_id = 1;
|
||||
string chain_id = 1;
|
||||
string node_name = 2;
|
||||
uint64 staked_token_amount = 3;
|
||||
string asset_id = 4;
|
||||
@@ -379,16 +379,16 @@ message AddPermissionlessValidatorResponse {
|
||||
ClusterInfo cluster_info = 1;
|
||||
}
|
||||
|
||||
message RemoveSubnetValidatorSpec {
|
||||
string subnet_id = 1;
|
||||
message RemoveChainValidatorSpec {
|
||||
string chain_id = 1;
|
||||
repeated string node_names = 2;
|
||||
}
|
||||
|
||||
message RemoveSubnetValidatorRequest {
|
||||
repeated RemoveSubnetValidatorSpec validator_spec = 1;
|
||||
message RemoveChainValidatorRequest {
|
||||
repeated RemoveChainValidatorSpec validator_spec = 1;
|
||||
}
|
||||
|
||||
message RemoveSubnetValidatorResponse {
|
||||
message RemoveChainValidatorResponse {
|
||||
ClusterInfo cluster_info = 1;
|
||||
}
|
||||
|
||||
@@ -396,10 +396,10 @@ message BlockchainSpec {
|
||||
string vm_name = 1;
|
||||
// either file path or file contents
|
||||
string genesis = 2;
|
||||
// either a subnet_id is given for a previously created subnet,
|
||||
// or a subnet specification is given for a new subnet generation
|
||||
optional string subnet_id = 3;
|
||||
optional SubnetSpec subnet_spec = 4;
|
||||
// either a chain_id is given for a previously created chain,
|
||||
// or a chain specification is given for a new chain generation
|
||||
optional string chain_id = 3;
|
||||
optional ChainSpec chain_spec = 4;
|
||||
// General chain config, either file path or file contents
|
||||
string chain_config = 5;
|
||||
// either file path or file contents
|
||||
@@ -413,15 +413,15 @@ message CreateBlockchainsRequest {
|
||||
// The list of:
|
||||
// - custom chain's VM name
|
||||
// - genesis file path
|
||||
// - (optional) subnet id to use.
|
||||
// - (optional) chain id to use.
|
||||
// - chain config file path
|
||||
// - network upgrade file path
|
||||
// - subnet config file path
|
||||
// - chain config file path
|
||||
// - chain config file path for specific nodes
|
||||
//
|
||||
// The matching file with the name in "ids.ID" format must exist.
|
||||
// e.g., ids.ToID(hashing.ComputeHash256("subnetevm")).String()
|
||||
// e.g., subnet-cli create VMID subnetevm
|
||||
// e.g., ids.ToID(hashing.ComputeHash256("chainevm")).String()
|
||||
// e.g., chain-cli create VMID chainevm
|
||||
//
|
||||
// If this field is set to none (by default), the node/network-runner
|
||||
// will return error
|
||||
@@ -433,13 +433,13 @@ message CreateBlockchainsResponse {
|
||||
repeated string chain_ids = 2;
|
||||
}
|
||||
|
||||
message CreateSubnetsRequest {
|
||||
repeated SubnetSpec subnet_specs = 1;
|
||||
message CreateChainsRequest {
|
||||
repeated ChainSpec chain_specs = 1;
|
||||
}
|
||||
|
||||
message CreateSubnetsResponse {
|
||||
message CreateChainsResponse {
|
||||
ClusterInfo cluster_info = 1;
|
||||
repeated string subnet_ids = 2;
|
||||
repeated string chain_ids = 2;
|
||||
}
|
||||
|
||||
message HealthRequest {}
|
||||
@@ -480,7 +480,7 @@ message RestartNodeRequest {
|
||||
|
||||
// Optional fields are set to the previous values if empty.
|
||||
optional string exec_path = 2;
|
||||
optional string whitelisted_subnets = 3;
|
||||
optional string whitelisted_chains = 3;
|
||||
|
||||
// Map of chain name to config file contents.
|
||||
// If specified, will create a file "chainname/config.json" with
|
||||
@@ -492,10 +492,10 @@ message RestartNodeRequest {
|
||||
// the contents provided here.
|
||||
map<string, string> upgrade_configs = 5;
|
||||
|
||||
// Map of subnet id to subnet config file contents.
|
||||
// If specified, will create a file "subnetid.json" under subnets config dir with
|
||||
// Map of chain id to chain config file contents.
|
||||
// If specified, will create a file "chainid.json" under chains config dir with
|
||||
// the contents provided here.
|
||||
map<string, string> subnet_configs = 6;
|
||||
map<string, string> chain_config_files = 6;
|
||||
|
||||
// Plugin dir from which to load all custom VM executables.
|
||||
string plugin_dir = 7;
|
||||
@@ -544,10 +544,10 @@ message AddNodeRequest {
|
||||
// the contents provided here.
|
||||
map<string, string> upgrade_configs = 5;
|
||||
|
||||
// Map of subnet id to subnet config file contents.
|
||||
// If specified, will create a file "subnetid.json" under subnets config dir with
|
||||
// Map of chain id to chain config file contents.
|
||||
// If specified, will create a file "chainid.json" under chains config dir with
|
||||
// the contents provided here.
|
||||
map<string, string> subnet_configs = 6;
|
||||
map<string, string> chain_config_files = 6;
|
||||
|
||||
// Plugin dir from which to load all custom VM executables.
|
||||
string plugin_dir = 7;
|
||||
@@ -600,7 +600,7 @@ message LoadSnapshotRequest {
|
||||
map<string, string> upgrade_configs = 6;
|
||||
optional string global_node_config = 7;
|
||||
optional bool reassign_ports_if_used = 8;
|
||||
map<string, string> subnet_configs = 9;
|
||||
map<string, string> chain_config_files = 9;
|
||||
}
|
||||
|
||||
message LoadSnapshotResponse {
|
||||
|
||||
+157
-134
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc-gen-go-grpc v1.6.0
|
||||
// - protoc (unknown)
|
||||
// source: rpcpb/rpc.proto
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
PingService_Ping_FullMethodName = "/rpcpb.PingService/Ping"
|
||||
@@ -38,8 +38,9 @@ func NewPingServiceClient(cc grpc.ClientConnInterface) PingServiceClient {
|
||||
}
|
||||
|
||||
func (c *pingServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PingResponse)
|
||||
err := c.cc.Invoke(ctx, PingService_Ping_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, PingService_Ping_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -48,20 +49,24 @@ func (c *pingServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...g
|
||||
|
||||
// PingServiceServer is the server API for PingService service.
|
||||
// All implementations must embed UnimplementedPingServiceServer
|
||||
// for forward compatibility
|
||||
// for forward compatibility.
|
||||
type PingServiceServer interface {
|
||||
Ping(context.Context, *PingRequest) (*PingResponse, error)
|
||||
mustEmbedUnimplementedPingServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedPingServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedPingServiceServer struct {
|
||||
}
|
||||
// UnimplementedPingServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedPingServiceServer struct{}
|
||||
|
||||
func (UnimplementedPingServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Ping not implemented")
|
||||
}
|
||||
func (UnimplementedPingServiceServer) mustEmbedUnimplementedPingServiceServer() {}
|
||||
func (UnimplementedPingServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafePingServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to PingServiceServer will
|
||||
@@ -71,6 +76,13 @@ type UnsafePingServiceServer interface {
|
||||
}
|
||||
|
||||
func RegisterPingServiceServer(s grpc.ServiceRegistrar, srv PingServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedPingServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&PingService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
@@ -112,10 +124,10 @@ const (
|
||||
ControlService_RPCVersion_FullMethodName = "/rpcpb.ControlService/RPCVersion"
|
||||
ControlService_Start_FullMethodName = "/rpcpb.ControlService/Start"
|
||||
ControlService_CreateBlockchains_FullMethodName = "/rpcpb.ControlService/CreateBlockchains"
|
||||
ControlService_TransformElasticSubnets_FullMethodName = "/rpcpb.ControlService/TransformElasticSubnets"
|
||||
ControlService_TransformElasticChains_FullMethodName = "/rpcpb.ControlService/TransformElasticChains"
|
||||
ControlService_AddPermissionlessValidator_FullMethodName = "/rpcpb.ControlService/AddPermissionlessValidator"
|
||||
ControlService_RemoveSubnetValidator_FullMethodName = "/rpcpb.ControlService/RemoveSubnetValidator"
|
||||
ControlService_CreateSubnets_FullMethodName = "/rpcpb.ControlService/CreateSubnets"
|
||||
ControlService_RemoveChainValidator_FullMethodName = "/rpcpb.ControlService/RemoveChainValidator"
|
||||
ControlService_CreateChains_FullMethodName = "/rpcpb.ControlService/CreateChains"
|
||||
ControlService_Health_FullMethodName = "/rpcpb.ControlService/Health"
|
||||
ControlService_URIs_FullMethodName = "/rpcpb.ControlService/URIs"
|
||||
ControlService_WaitForHealthy_FullMethodName = "/rpcpb.ControlService/WaitForHealthy"
|
||||
@@ -142,15 +154,15 @@ type ControlServiceClient interface {
|
||||
RPCVersion(ctx context.Context, in *RPCVersionRequest, opts ...grpc.CallOption) (*RPCVersionResponse, error)
|
||||
Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error)
|
||||
CreateBlockchains(ctx context.Context, in *CreateBlockchainsRequest, opts ...grpc.CallOption) (*CreateBlockchainsResponse, error)
|
||||
TransformElasticSubnets(ctx context.Context, in *TransformElasticSubnetsRequest, opts ...grpc.CallOption) (*TransformElasticSubnetsResponse, error)
|
||||
TransformElasticChains(ctx context.Context, in *TransformElasticChainsRequest, opts ...grpc.CallOption) (*TransformElasticChainsResponse, error)
|
||||
AddPermissionlessValidator(ctx context.Context, in *AddPermissionlessValidatorRequest, opts ...grpc.CallOption) (*AddPermissionlessValidatorResponse, error)
|
||||
RemoveSubnetValidator(ctx context.Context, in *RemoveSubnetValidatorRequest, opts ...grpc.CallOption) (*RemoveSubnetValidatorResponse, error)
|
||||
CreateSubnets(ctx context.Context, in *CreateSubnetsRequest, opts ...grpc.CallOption) (*CreateSubnetsResponse, error)
|
||||
RemoveChainValidator(ctx context.Context, in *RemoveChainValidatorRequest, opts ...grpc.CallOption) (*RemoveChainValidatorResponse, error)
|
||||
CreateChains(ctx context.Context, in *CreateChainsRequest, opts ...grpc.CallOption) (*CreateChainsResponse, error)
|
||||
Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error)
|
||||
URIs(ctx context.Context, in *URIsRequest, opts ...grpc.CallOption) (*URIsResponse, error)
|
||||
WaitForHealthy(ctx context.Context, in *WaitForHealthyRequest, opts ...grpc.CallOption) (*WaitForHealthyResponse, error)
|
||||
Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error)
|
||||
StreamStatus(ctx context.Context, in *StreamStatusRequest, opts ...grpc.CallOption) (ControlService_StreamStatusClient, error)
|
||||
StreamStatus(ctx context.Context, in *StreamStatusRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamStatusResponse], error)
|
||||
RemoveNode(ctx context.Context, in *RemoveNodeRequest, opts ...grpc.CallOption) (*RemoveNodeResponse, error)
|
||||
AddNode(ctx context.Context, in *AddNodeRequest, opts ...grpc.CallOption) (*AddNodeResponse, error)
|
||||
RestartNode(ctx context.Context, in *RestartNodeRequest, opts ...grpc.CallOption) (*RestartNodeResponse, error)
|
||||
@@ -174,8 +186,9 @@ func NewControlServiceClient(cc grpc.ClientConnInterface) ControlServiceClient {
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) RPCVersion(ctx context.Context, in *RPCVersionRequest, opts ...grpc.CallOption) (*RPCVersionResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RPCVersionResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_RPCVersion_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_RPCVersion_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -183,8 +196,9 @@ func (c *controlServiceClient) RPCVersion(ctx context.Context, in *RPCVersionReq
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(StartResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_Start_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_Start_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -192,17 +206,19 @@ func (c *controlServiceClient) Start(ctx context.Context, in *StartRequest, opts
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) CreateBlockchains(ctx context.Context, in *CreateBlockchainsRequest, opts ...grpc.CallOption) (*CreateBlockchainsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(CreateBlockchainsResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_CreateBlockchains_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_CreateBlockchains_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) TransformElasticSubnets(ctx context.Context, in *TransformElasticSubnetsRequest, opts ...grpc.CallOption) (*TransformElasticSubnetsResponse, error) {
|
||||
out := new(TransformElasticSubnetsResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_TransformElasticSubnets_FullMethodName, in, out, opts...)
|
||||
func (c *controlServiceClient) TransformElasticChains(ctx context.Context, in *TransformElasticChainsRequest, opts ...grpc.CallOption) (*TransformElasticChainsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(TransformElasticChainsResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_TransformElasticChains_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -210,26 +226,29 @@ func (c *controlServiceClient) TransformElasticSubnets(ctx context.Context, in *
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) AddPermissionlessValidator(ctx context.Context, in *AddPermissionlessValidatorRequest, opts ...grpc.CallOption) (*AddPermissionlessValidatorResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AddPermissionlessValidatorResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_AddPermissionlessValidator_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_AddPermissionlessValidator_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) RemoveSubnetValidator(ctx context.Context, in *RemoveSubnetValidatorRequest, opts ...grpc.CallOption) (*RemoveSubnetValidatorResponse, error) {
|
||||
out := new(RemoveSubnetValidatorResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_RemoveSubnetValidator_FullMethodName, in, out, opts...)
|
||||
func (c *controlServiceClient) RemoveChainValidator(ctx context.Context, in *RemoveChainValidatorRequest, opts ...grpc.CallOption) (*RemoveChainValidatorResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RemoveChainValidatorResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_RemoveChainValidator_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) CreateSubnets(ctx context.Context, in *CreateSubnetsRequest, opts ...grpc.CallOption) (*CreateSubnetsResponse, error) {
|
||||
out := new(CreateSubnetsResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_CreateSubnets_FullMethodName, in, out, opts...)
|
||||
func (c *controlServiceClient) CreateChains(ctx context.Context, in *CreateChainsRequest, opts ...grpc.CallOption) (*CreateChainsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(CreateChainsResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_CreateChains_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -237,8 +256,9 @@ func (c *controlServiceClient) CreateSubnets(ctx context.Context, in *CreateSubn
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(HealthResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_Health_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_Health_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -246,8 +266,9 @@ func (c *controlServiceClient) Health(ctx context.Context, in *HealthRequest, op
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) URIs(ctx context.Context, in *URIsRequest, opts ...grpc.CallOption) (*URIsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(URIsResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_URIs_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_URIs_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -255,8 +276,9 @@ func (c *controlServiceClient) URIs(ctx context.Context, in *URIsRequest, opts .
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) WaitForHealthy(ctx context.Context, in *WaitForHealthyRequest, opts ...grpc.CallOption) (*WaitForHealthyResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(WaitForHealthyResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_WaitForHealthy_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_WaitForHealthy_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -264,20 +286,22 @@ func (c *controlServiceClient) WaitForHealthy(ctx context.Context, in *WaitForHe
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(StatusResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_Status_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_Status_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) StreamStatus(ctx context.Context, in *StreamStatusRequest, opts ...grpc.CallOption) (ControlService_StreamStatusClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &ControlService_ServiceDesc.Streams[0], ControlService_StreamStatus_FullMethodName, opts...)
|
||||
func (c *controlServiceClient) StreamStatus(ctx context.Context, in *StreamStatusRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamStatusResponse], error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &ControlService_ServiceDesc.Streams[0], ControlService_StreamStatus_FullMethodName, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &controlServiceStreamStatusClient{stream}
|
||||
x := &grpc.GenericClientStream[StreamStatusRequest, StreamStatusResponse]{ClientStream: stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -287,26 +311,13 @@ func (c *controlServiceClient) StreamStatus(ctx context.Context, in *StreamStatu
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type ControlService_StreamStatusClient interface {
|
||||
Recv() (*StreamStatusResponse, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type controlServiceStreamStatusClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *controlServiceStreamStatusClient) Recv() (*StreamStatusResponse, error) {
|
||||
m := new(StreamStatusResponse)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type ControlService_StreamStatusClient = grpc.ServerStreamingClient[StreamStatusResponse]
|
||||
|
||||
func (c *controlServiceClient) RemoveNode(ctx context.Context, in *RemoveNodeRequest, opts ...grpc.CallOption) (*RemoveNodeResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RemoveNodeResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_RemoveNode_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_RemoveNode_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -314,8 +325,9 @@ func (c *controlServiceClient) RemoveNode(ctx context.Context, in *RemoveNodeReq
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) AddNode(ctx context.Context, in *AddNodeRequest, opts ...grpc.CallOption) (*AddNodeResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AddNodeResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_AddNode_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_AddNode_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -323,8 +335,9 @@ func (c *controlServiceClient) AddNode(ctx context.Context, in *AddNodeRequest,
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) RestartNode(ctx context.Context, in *RestartNodeRequest, opts ...grpc.CallOption) (*RestartNodeResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RestartNodeResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_RestartNode_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_RestartNode_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -332,8 +345,9 @@ func (c *controlServiceClient) RestartNode(ctx context.Context, in *RestartNodeR
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) PauseNode(ctx context.Context, in *PauseNodeRequest, opts ...grpc.CallOption) (*PauseNodeResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PauseNodeResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_PauseNode_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_PauseNode_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -341,8 +355,9 @@ func (c *controlServiceClient) PauseNode(ctx context.Context, in *PauseNodeReque
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) ResumeNode(ctx context.Context, in *ResumeNodeRequest, opts ...grpc.CallOption) (*ResumeNodeResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ResumeNodeResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_ResumeNode_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_ResumeNode_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -350,8 +365,9 @@ func (c *controlServiceClient) ResumeNode(ctx context.Context, in *ResumeNodeReq
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) Stop(ctx context.Context, in *StopRequest, opts ...grpc.CallOption) (*StopResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(StopResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_Stop_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_Stop_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -359,8 +375,9 @@ func (c *controlServiceClient) Stop(ctx context.Context, in *StopRequest, opts .
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) AttachPeer(ctx context.Context, in *AttachPeerRequest, opts ...grpc.CallOption) (*AttachPeerResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AttachPeerResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_AttachPeer_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_AttachPeer_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -368,8 +385,9 @@ func (c *controlServiceClient) AttachPeer(ctx context.Context, in *AttachPeerReq
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) SendOutboundMessage(ctx context.Context, in *SendOutboundMessageRequest, opts ...grpc.CallOption) (*SendOutboundMessageResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(SendOutboundMessageResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_SendOutboundMessage_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_SendOutboundMessage_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -377,8 +395,9 @@ func (c *controlServiceClient) SendOutboundMessage(ctx context.Context, in *Send
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) SaveSnapshot(ctx context.Context, in *SaveSnapshotRequest, opts ...grpc.CallOption) (*SaveSnapshotResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(SaveSnapshotResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_SaveSnapshot_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_SaveSnapshot_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -386,8 +405,9 @@ func (c *controlServiceClient) SaveSnapshot(ctx context.Context, in *SaveSnapsho
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) LoadSnapshot(ctx context.Context, in *LoadSnapshotRequest, opts ...grpc.CallOption) (*LoadSnapshotResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(LoadSnapshotResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_LoadSnapshot_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_LoadSnapshot_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -395,8 +415,9 @@ func (c *controlServiceClient) LoadSnapshot(ctx context.Context, in *LoadSnapsho
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) RemoveSnapshot(ctx context.Context, in *RemoveSnapshotRequest, opts ...grpc.CallOption) (*RemoveSnapshotResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RemoveSnapshotResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_RemoveSnapshot_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_RemoveSnapshot_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -404,8 +425,9 @@ func (c *controlServiceClient) RemoveSnapshot(ctx context.Context, in *RemoveSna
|
||||
}
|
||||
|
||||
func (c *controlServiceClient) GetSnapshotNames(ctx context.Context, in *GetSnapshotNamesRequest, opts ...grpc.CallOption) (*GetSnapshotNamesResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetSnapshotNamesResponse)
|
||||
err := c.cc.Invoke(ctx, ControlService_GetSnapshotNames_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, ControlService_GetSnapshotNames_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -414,20 +436,20 @@ func (c *controlServiceClient) GetSnapshotNames(ctx context.Context, in *GetSnap
|
||||
|
||||
// ControlServiceServer is the server API for ControlService service.
|
||||
// All implementations must embed UnimplementedControlServiceServer
|
||||
// for forward compatibility
|
||||
// for forward compatibility.
|
||||
type ControlServiceServer interface {
|
||||
RPCVersion(context.Context, *RPCVersionRequest) (*RPCVersionResponse, error)
|
||||
Start(context.Context, *StartRequest) (*StartResponse, error)
|
||||
CreateBlockchains(context.Context, *CreateBlockchainsRequest) (*CreateBlockchainsResponse, error)
|
||||
TransformElasticSubnets(context.Context, *TransformElasticSubnetsRequest) (*TransformElasticSubnetsResponse, error)
|
||||
TransformElasticChains(context.Context, *TransformElasticChainsRequest) (*TransformElasticChainsResponse, error)
|
||||
AddPermissionlessValidator(context.Context, *AddPermissionlessValidatorRequest) (*AddPermissionlessValidatorResponse, error)
|
||||
RemoveSubnetValidator(context.Context, *RemoveSubnetValidatorRequest) (*RemoveSubnetValidatorResponse, error)
|
||||
CreateSubnets(context.Context, *CreateSubnetsRequest) (*CreateSubnetsResponse, error)
|
||||
RemoveChainValidator(context.Context, *RemoveChainValidatorRequest) (*RemoveChainValidatorResponse, error)
|
||||
CreateChains(context.Context, *CreateChainsRequest) (*CreateChainsResponse, error)
|
||||
Health(context.Context, *HealthRequest) (*HealthResponse, error)
|
||||
URIs(context.Context, *URIsRequest) (*URIsResponse, error)
|
||||
WaitForHealthy(context.Context, *WaitForHealthyRequest) (*WaitForHealthyResponse, error)
|
||||
Status(context.Context, *StatusRequest) (*StatusResponse, error)
|
||||
StreamStatus(*StreamStatusRequest, ControlService_StreamStatusServer) error
|
||||
StreamStatus(*StreamStatusRequest, grpc.ServerStreamingServer[StreamStatusResponse]) error
|
||||
RemoveNode(context.Context, *RemoveNodeRequest) (*RemoveNodeResponse, error)
|
||||
AddNode(context.Context, *AddNodeRequest) (*AddNodeResponse, error)
|
||||
RestartNode(context.Context, *RestartNodeRequest) (*RestartNodeResponse, error)
|
||||
@@ -443,83 +465,87 @@ type ControlServiceServer interface {
|
||||
mustEmbedUnimplementedControlServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedControlServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedControlServiceServer struct {
|
||||
}
|
||||
// UnimplementedControlServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedControlServiceServer struct{}
|
||||
|
||||
func (UnimplementedControlServiceServer) RPCVersion(context.Context, *RPCVersionRequest) (*RPCVersionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RPCVersion not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method RPCVersion not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) Start(context.Context, *StartRequest) (*StartResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Start not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Start not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) CreateBlockchains(context.Context, *CreateBlockchainsRequest) (*CreateBlockchainsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateBlockchains not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method CreateBlockchains not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) TransformElasticSubnets(context.Context, *TransformElasticSubnetsRequest) (*TransformElasticSubnetsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method TransformElasticSubnets not implemented")
|
||||
func (UnimplementedControlServiceServer) TransformElasticChains(context.Context, *TransformElasticChainsRequest) (*TransformElasticChainsResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method TransformElasticChains not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) AddPermissionlessValidator(context.Context, *AddPermissionlessValidatorRequest) (*AddPermissionlessValidatorResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddPermissionlessValidator not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method AddPermissionlessValidator not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) RemoveSubnetValidator(context.Context, *RemoveSubnetValidatorRequest) (*RemoveSubnetValidatorResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveSubnetValidator not implemented")
|
||||
func (UnimplementedControlServiceServer) RemoveChainValidator(context.Context, *RemoveChainValidatorRequest) (*RemoveChainValidatorResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveChainValidator not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) CreateSubnets(context.Context, *CreateSubnetsRequest) (*CreateSubnetsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateSubnets not implemented")
|
||||
func (UnimplementedControlServiceServer) CreateChains(context.Context, *CreateChainsRequest) (*CreateChainsResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method CreateChains not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) Health(context.Context, *HealthRequest) (*HealthResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Health not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Health not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) URIs(context.Context, *URIsRequest) (*URIsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method URIs not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method URIs not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) WaitForHealthy(context.Context, *WaitForHealthyRequest) (*WaitForHealthyResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method WaitForHealthy not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method WaitForHealthy not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) Status(context.Context, *StatusRequest) (*StatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Status not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Status not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) StreamStatus(*StreamStatusRequest, ControlService_StreamStatusServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method StreamStatus not implemented")
|
||||
func (UnimplementedControlServiceServer) StreamStatus(*StreamStatusRequest, grpc.ServerStreamingServer[StreamStatusResponse]) error {
|
||||
return status.Error(codes.Unimplemented, "method StreamStatus not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) RemoveNode(context.Context, *RemoveNodeRequest) (*RemoveNodeResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveNode not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveNode not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) AddNode(context.Context, *AddNodeRequest) (*AddNodeResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddNode not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method AddNode not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) RestartNode(context.Context, *RestartNodeRequest) (*RestartNodeResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RestartNode not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method RestartNode not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) PauseNode(context.Context, *PauseNodeRequest) (*PauseNodeResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method PauseNode not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method PauseNode not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) ResumeNode(context.Context, *ResumeNodeRequest) (*ResumeNodeResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ResumeNode not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method ResumeNode not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) Stop(context.Context, *StopRequest) (*StopResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Stop not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) AttachPeer(context.Context, *AttachPeerRequest) (*AttachPeerResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AttachPeer not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method AttachPeer not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) SendOutboundMessage(context.Context, *SendOutboundMessageRequest) (*SendOutboundMessageResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SendOutboundMessage not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method SendOutboundMessage not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) SaveSnapshot(context.Context, *SaveSnapshotRequest) (*SaveSnapshotResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SaveSnapshot not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method SaveSnapshot not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) LoadSnapshot(context.Context, *LoadSnapshotRequest) (*LoadSnapshotResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method LoadSnapshot not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method LoadSnapshot not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) RemoveSnapshot(context.Context, *RemoveSnapshotRequest) (*RemoveSnapshotResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveSnapshot not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveSnapshot not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) GetSnapshotNames(context.Context, *GetSnapshotNamesRequest) (*GetSnapshotNamesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetSnapshotNames not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method GetSnapshotNames not implemented")
|
||||
}
|
||||
func (UnimplementedControlServiceServer) mustEmbedUnimplementedControlServiceServer() {}
|
||||
func (UnimplementedControlServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeControlServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ControlServiceServer will
|
||||
@@ -529,6 +555,13 @@ type UnsafeControlServiceServer interface {
|
||||
}
|
||||
|
||||
func RegisterControlServiceServer(s grpc.ServiceRegistrar, srv ControlServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedControlServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&ControlService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
@@ -586,20 +619,20 @@ func _ControlService_CreateBlockchains_Handler(srv interface{}, ctx context.Cont
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ControlService_TransformElasticSubnets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(TransformElasticSubnetsRequest)
|
||||
func _ControlService_TransformElasticChains_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(TransformElasticChainsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ControlServiceServer).TransformElasticSubnets(ctx, in)
|
||||
return srv.(ControlServiceServer).TransformElasticChains(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ControlService_TransformElasticSubnets_FullMethodName,
|
||||
FullMethod: ControlService_TransformElasticChains_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ControlServiceServer).TransformElasticSubnets(ctx, req.(*TransformElasticSubnetsRequest))
|
||||
return srv.(ControlServiceServer).TransformElasticChains(ctx, req.(*TransformElasticChainsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -622,38 +655,38 @@ func _ControlService_AddPermissionlessValidator_Handler(srv interface{}, ctx con
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ControlService_RemoveSubnetValidator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveSubnetValidatorRequest)
|
||||
func _ControlService_RemoveChainValidator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveChainValidatorRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ControlServiceServer).RemoveSubnetValidator(ctx, in)
|
||||
return srv.(ControlServiceServer).RemoveChainValidator(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ControlService_RemoveSubnetValidator_FullMethodName,
|
||||
FullMethod: ControlService_RemoveChainValidator_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ControlServiceServer).RemoveSubnetValidator(ctx, req.(*RemoveSubnetValidatorRequest))
|
||||
return srv.(ControlServiceServer).RemoveChainValidator(ctx, req.(*RemoveChainValidatorRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ControlService_CreateSubnets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateSubnetsRequest)
|
||||
func _ControlService_CreateChains_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateChainsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ControlServiceServer).CreateSubnets(ctx, in)
|
||||
return srv.(ControlServiceServer).CreateChains(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ControlService_CreateSubnets_FullMethodName,
|
||||
FullMethod: ControlService_CreateChains_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ControlServiceServer).CreateSubnets(ctx, req.(*CreateSubnetsRequest))
|
||||
return srv.(ControlServiceServer).CreateChains(ctx, req.(*CreateChainsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -735,21 +768,11 @@ func _ControlService_StreamStatus_Handler(srv interface{}, stream grpc.ServerStr
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(ControlServiceServer).StreamStatus(m, &controlServiceStreamStatusServer{stream})
|
||||
return srv.(ControlServiceServer).StreamStatus(m, &grpc.GenericServerStream[StreamStatusRequest, StreamStatusResponse]{ServerStream: stream})
|
||||
}
|
||||
|
||||
type ControlService_StreamStatusServer interface {
|
||||
Send(*StreamStatusResponse) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type controlServiceStreamStatusServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *controlServiceStreamStatusServer) Send(m *StreamStatusResponse) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type ControlService_StreamStatusServer = grpc.ServerStreamingServer[StreamStatusResponse]
|
||||
|
||||
func _ControlService_RemoveNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveNodeRequest)
|
||||
@@ -987,20 +1010,20 @@ var ControlService_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _ControlService_CreateBlockchains_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "TransformElasticSubnets",
|
||||
Handler: _ControlService_TransformElasticSubnets_Handler,
|
||||
MethodName: "TransformElasticChains",
|
||||
Handler: _ControlService_TransformElasticChains_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddPermissionlessValidator",
|
||||
Handler: _ControlService_AddPermissionlessValidator_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RemoveSubnetValidator",
|
||||
Handler: _ControlService_RemoveSubnetValidator_Handler,
|
||||
MethodName: "RemoveChainValidator",
|
||||
Handler: _ControlService_RemoveChainValidator_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateSubnets",
|
||||
Handler: _ControlService_CreateSubnets_Handler,
|
||||
MethodName: "CreateChains",
|
||||
Handler: _ControlService_CreateChains_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Health",
|
||||
|
||||
+56
-56
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package server
|
||||
|
||||
@@ -71,14 +71,14 @@ type localNetwork struct {
|
||||
stopCh chan struct{}
|
||||
stopOnce sync.Once
|
||||
|
||||
subnets map[string]*rpcpb.SubnetInfo
|
||||
chains map[string]*rpcpb.ChainInfo
|
||||
|
||||
prometheusConfPath string
|
||||
}
|
||||
|
||||
type chainInfo struct {
|
||||
info *rpcpb.CustomChainInfo
|
||||
subnetID ids.ID
|
||||
chainID ids.ID
|
||||
blockchainID ids.ID
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ type localNetworkOptions struct {
|
||||
execPath string
|
||||
rootDataDir string
|
||||
numNodes uint32
|
||||
trackSubnets string
|
||||
trackChains string
|
||||
redirectNodesOutput bool
|
||||
globalNodeConfig string
|
||||
|
||||
@@ -97,8 +97,8 @@ type localNetworkOptions struct {
|
||||
chainConfigs map[string]string
|
||||
// upgrade configs to be added to the network, besides the ones in default config, or saved snapshot
|
||||
upgradeConfigs map[string]string
|
||||
// subnet configs to be added to the network, besides the ones in default config, or saved snapshot
|
||||
subnetConfigs map[string]string
|
||||
// P-chain configs to be added to the network, besides the ones in default config, or saved snapshot
|
||||
pChainConfigs map[string]string
|
||||
|
||||
snapshotsDir string
|
||||
|
||||
@@ -130,7 +130,7 @@ func newLocalNetwork(opts localNetworkOptions) (*localNetwork, error) {
|
||||
customChainIDToInfo: make(map[ids.ID]chainInfo),
|
||||
stopCh: make(chan struct{}),
|
||||
nodeInfos: make(map[string]*rpcpb.NodeInfo),
|
||||
subnets: make(map[string]*rpcpb.SubnetInfo),
|
||||
chains: make(map[string]*rpcpb.ChainInfo),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -211,8 +211,8 @@ func (lc *localNetwork) createConfig() error {
|
||||
if cfg.NodeConfigs[i].UpgradeConfigFiles == nil {
|
||||
cfg.NodeConfigs[i].UpgradeConfigFiles = map[string]string{}
|
||||
}
|
||||
if cfg.NodeConfigs[i].SubnetConfigFiles == nil {
|
||||
cfg.NodeConfigs[i].SubnetConfigFiles = map[string]string{}
|
||||
if cfg.NodeConfigs[i].ChainConfigFiles == nil {
|
||||
cfg.NodeConfigs[i].ChainConfigFiles = map[string]string{}
|
||||
}
|
||||
|
||||
for k, v := range lc.options.chainConfigs {
|
||||
@@ -221,8 +221,8 @@ func (lc *localNetwork) createConfig() error {
|
||||
for k, v := range lc.options.upgradeConfigs {
|
||||
cfg.NodeConfigs[i].UpgradeConfigFiles[k] = v
|
||||
}
|
||||
for k, v := range lc.options.subnetConfigs {
|
||||
cfg.NodeConfigs[i].SubnetConfigFiles[k] = v
|
||||
for k, v := range lc.options.chainConfigs {
|
||||
cfg.NodeConfigs[i].ChainConfigFiles[k] = v
|
||||
}
|
||||
|
||||
if lc.options.dynamicPorts {
|
||||
@@ -231,8 +231,8 @@ func (lc *localNetwork) createConfig() error {
|
||||
delete(cfg.NodeConfigs[i].Flags, config.StakingPortKey)
|
||||
}
|
||||
|
||||
if lc.options.trackSubnets != "" {
|
||||
cfg.NodeConfigs[i].Flags[config.TrackNetsKey] = lc.options.trackSubnets
|
||||
if lc.options.trackChains != "" {
|
||||
cfg.NodeConfigs[i].Flags[config.TrackNetsKey] = lc.options.trackChains
|
||||
}
|
||||
|
||||
cfg.NodeConfigs[i].BinaryPath = lc.execPath
|
||||
@@ -301,7 +301,7 @@ func (lc *localNetwork) Start(ctx context.Context) error {
|
||||
// Assumes [lc.lock] isn't held.
|
||||
func (lc *localNetwork) CreateChains(
|
||||
ctx context.Context,
|
||||
chainSpecs []network.BlockchainSpec, // VM name + genesis bytes
|
||||
chainSpecs []network.ChainSpec, // VM name + genesis bytes
|
||||
) ([]ids.ID, error) {
|
||||
lc.lock.Lock()
|
||||
defer lc.lock.Unlock()
|
||||
@@ -327,7 +327,7 @@ func (lc *localNetwork) CreateChains(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chainIDs, err := lc.nw.CreateBlockchains(ctx, chainSpecs)
|
||||
chainIDs, err := lc.nw.CreateChains(ctx, chainSpecs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -378,7 +378,7 @@ func (lc *localNetwork) AddPermissionlessValidators(ctx context.Context, validat
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lc *localNetwork) RemoveSubnetValidator(ctx context.Context, validatorSpecs []network.RemoveSubnetValidatorSpec) error {
|
||||
func (lc *localNetwork) RemoveChainValidator(ctx context.Context, validatorSpecs []network.RemoveChainValidatorSpec) error {
|
||||
lc.lock.Lock()
|
||||
defer lc.lock.Unlock()
|
||||
|
||||
@@ -404,7 +404,7 @@ func (lc *localNetwork) RemoveSubnetValidator(ctx context.Context, validatorSpec
|
||||
return err
|
||||
}
|
||||
|
||||
err := lc.nw.RemoveSubnetValidators(ctx, validatorSpecs)
|
||||
err := lc.nw.RemoveChainValidators(ctx, validatorSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -413,16 +413,16 @@ func (lc *localNetwork) RemoveSubnetValidator(ctx context.Context, validatorSpec
|
||||
return err
|
||||
}
|
||||
|
||||
ux.Print(lc.log, luxlog.Green.Wrap(luxlog.Bold.Wrap("finished removing subnet validators")))
|
||||
ux.Print(lc.log, luxlog.Green.Wrap(luxlog.Bold.Wrap("finished removing chain validators")))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lc *localNetwork) TransformSubnets(ctx context.Context, elasticSubnetSpecs []network.ElasticSubnetSpec) ([]ids.ID, []ids.ID, error) {
|
||||
func (lc *localNetwork) TransformChains(ctx context.Context, elasticChainSpecs []network.ElasticChainSpec) ([]ids.ID, []ids.ID, error) {
|
||||
lc.lock.Lock()
|
||||
defer lc.lock.Unlock()
|
||||
|
||||
if len(elasticSubnetSpecs) == 0 {
|
||||
ux.Print(lc.log, luxlog.Orange.Wrap(luxlog.Bold.Wrap("no subnets specified...")))
|
||||
if len(elasticChainSpecs) == 0 {
|
||||
ux.Print(lc.log, luxlog.Orange.Wrap(luxlog.Bold.Wrap("no chains specified...")))
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ func (lc *localNetwork) TransformSubnets(ctx context.Context, elasticSubnetSpecs
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
chainIDs, assetIDs, err := lc.nw.TransformSubnet(ctx, elasticSubnetSpecs)
|
||||
chainIDs, assetIDs, err := lc.nw.TransformChain(ctx, elasticChainSpecs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -452,18 +452,18 @@ func (lc *localNetwork) TransformSubnets(ctx context.Context, elasticSubnetSpecs
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ux.Print(lc.log, luxlog.Green.Wrap(luxlog.Bold.Wrap("finished transforming subnets")))
|
||||
ux.Print(lc.log, luxlog.Green.Wrap(luxlog.Bold.Wrap("finished transforming chains")))
|
||||
return chainIDs, assetIDs, nil
|
||||
}
|
||||
|
||||
// Creates the given number of subnets.
|
||||
// CreateParticipantGroups creates the given number of participant groups (validators).
|
||||
// Assumes [lc.lock] isn't held.
|
||||
func (lc *localNetwork) CreateSubnets(ctx context.Context, subnetSpecs []network.SubnetSpec) ([]ids.ID, error) {
|
||||
func (lc *localNetwork) CreateParticipantGroups(ctx context.Context, participantsSpecs []network.ParticipantsSpec) ([]ids.ID, error) {
|
||||
lc.lock.Lock()
|
||||
defer lc.lock.Unlock()
|
||||
|
||||
if len(subnetSpecs) == 0 {
|
||||
ux.Print(lc.log, luxlog.Orange.Wrap(luxlog.Bold.Wrap("no subnets specified...")))
|
||||
if len(participantsSpecs) == 0 {
|
||||
ux.Print(lc.log, luxlog.Orange.Wrap(luxlog.Bold.Wrap("no chains specified...")))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@ func (lc *localNetwork) CreateSubnets(ctx context.Context, subnetSpecs []network
|
||||
return nil, err
|
||||
}
|
||||
|
||||
subnetIDs, err := lc.nw.CreateSubnets(ctx, subnetSpecs)
|
||||
chainIDs, err := lc.nw.CreateParticipantGroups(ctx, participantsSpecs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -493,8 +493,8 @@ func (lc *localNetwork) CreateSubnets(ctx context.Context, subnetSpecs []network
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ux.Print(lc.log, luxlog.Green.Wrap(luxlog.Bold.Wrap("finished adding subnets")))
|
||||
return subnetIDs, nil
|
||||
ux.Print(lc.log, luxlog.Green.Wrap(luxlog.Bold.Wrap("finished adding chains")))
|
||||
return chainIDs, nil
|
||||
}
|
||||
|
||||
// Loads a snapshot and sets [l.nw] to the network created from the snapshot.
|
||||
@@ -521,7 +521,7 @@ func (lc *localNetwork) LoadSnapshot(snapshotName string) error {
|
||||
lc.pluginDir,
|
||||
lc.options.chainConfigs,
|
||||
lc.options.upgradeConfigs,
|
||||
lc.options.subnetConfigs,
|
||||
lc.options.chainConfigs,
|
||||
globalNodeConfig,
|
||||
lc.options.reassignPortsIfUsed,
|
||||
)
|
||||
@@ -539,10 +539,10 @@ func (lc *localNetwork) LoadSnapshot(snapshotName string) error {
|
||||
|
||||
// Populates [lc.customChainIDToInfo] for all chains other than those on
|
||||
// the Primary Network (P-Chain, X-Chain, C-Chain.)
|
||||
// Populates [lc.subnets] with all subnets that exist.
|
||||
// Populates [lc.chains] with all chains that exist.
|
||||
// Doesn't contain the Primary network.
|
||||
// Assumes [lc.lock] is held.
|
||||
func (lc *localNetwork) updateSubnetInfo(ctx context.Context) error {
|
||||
func (lc *localNetwork) updateChainInfo(ctx context.Context) error {
|
||||
nodes, err := lc.nw.GetAllNodes()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -580,33 +580,33 @@ func (lc *localNetwork) updateSubnetInfo(ctx context.Context) error {
|
||||
info: &rpcpb.CustomChainInfo{
|
||||
ChainName: blockchain.Name,
|
||||
VmId: blockchain.VMID.String(),
|
||||
SubnetId: blockchain.NetID.String(),
|
||||
ChainId: blockchain.ID.String(),
|
||||
PchainId: blockchain.NetID.String(),
|
||||
BlockchainId: blockchain.ID.String(),
|
||||
},
|
||||
subnetID: blockchain.NetID,
|
||||
chainID: blockchain.NetID,
|
||||
blockchainID: blockchain.ID,
|
||||
}
|
||||
}
|
||||
|
||||
subnets, err := (*pChainClient).GetNets(ctx, nil)
|
||||
chains, err := (*pChainClient).GetNets(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
subnetIDList := []string{}
|
||||
for _, subnet := range subnets {
|
||||
chainIDList := []string{}
|
||||
for _, chain := range chains {
|
||||
// Skip both PlatformChainID and PrimaryNetworkID (which is ids.Empty)
|
||||
if subnet.ID != luxd_constants.PlatformChainID && subnet.ID != luxd_constants.PrimaryNetworkID {
|
||||
subnetIDList = append(subnetIDList, subnet.ID.String())
|
||||
if chain.ID != luxd_constants.PlatformChainID && chain.ID != luxd_constants.PrimaryNetworkID {
|
||||
chainIDList = append(chainIDList, chain.ID.String())
|
||||
}
|
||||
}
|
||||
|
||||
for _, subnetIDStr := range subnetIDList {
|
||||
subnetID, err := ids.FromString(subnetIDStr)
|
||||
for _, chainIDStr := range chainIDList {
|
||||
chainID, err := ids.FromString(chainIDStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vdrs, err := (*pChainClient).GetCurrentValidators(ctx, subnetID, nil)
|
||||
vdrs, err := (*pChainClient).GetCurrentValidators(ctx, chainID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -621,24 +621,24 @@ func (lc *localNetwork) updateSubnetInfo(ctx context.Context) error {
|
||||
}
|
||||
|
||||
isElastic := false
|
||||
elasticSubnetID := ids.Empty
|
||||
if _, _, err := (*pChainClient).GetCurrentSupply(ctx, subnetID); err == nil {
|
||||
elasticChainID := ids.Empty
|
||||
if _, _, err := (*pChainClient).GetCurrentSupply(ctx, chainID); err == nil {
|
||||
isElastic = true
|
||||
elasticSubnetID, err = lc.nw.GetElasticSubnetID(ctx, subnetID)
|
||||
elasticChainID, err = lc.nw.GetElasticChainID(ctx, chainID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
lc.subnets[subnetIDStr] = &rpcpb.SubnetInfo{
|
||||
lc.chains[chainIDStr] = &rpcpb.ChainInfo{
|
||||
IsElastic: isElastic,
|
||||
ElasticSubnetId: elasticSubnetID.String(),
|
||||
SubnetParticipants: &rpcpb.SubnetParticipants{NodeNames: nodeNameList},
|
||||
ElasticChainId: elasticChainID.String(),
|
||||
ChainParticipants: &rpcpb.ChainParticipants{NodeNames: nodeNameList},
|
||||
}
|
||||
}
|
||||
|
||||
for chainID, chainInfo := range lc.customChainIDToInfo {
|
||||
vs, err := (*pChainClient).GetCurrentValidators(ctx, chainInfo.subnetID, nil)
|
||||
vs, err := (*pChainClient).GetCurrentValidators(ctx, chainInfo.chainID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -651,7 +651,7 @@ func (lc *localNetwork) updateSubnetInfo(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
if len(nodeNames) != len(vs) {
|
||||
return fmt.Errorf("not all subnet validators are in network for subnet %s", chainInfo.subnetID.String())
|
||||
return fmt.Errorf("not all chain validators are in network for chain %s", chainInfo.chainID.String())
|
||||
}
|
||||
|
||||
sort.Strings(nodeNames)
|
||||
@@ -676,7 +676,7 @@ func (lc *localNetwork) AwaitHealthyAndUpdateNetworkInfo(ctx context.Context) er
|
||||
}
|
||||
|
||||
// Returns nil when [lc.nw] reports healthy.
|
||||
// Updates node and subnet info.
|
||||
// Updates node and chain info.
|
||||
// Assumes [lc.lock] is held.
|
||||
func (lc *localNetwork) awaitHealthyAndUpdateNetworkInfo(ctx context.Context) error {
|
||||
ux.Print(lc.log, luxlog.Blue.Wrap(luxlog.Bold.Wrap("waiting for all nodes to report healthy...")))
|
||||
@@ -689,7 +689,7 @@ func (lc *localNetwork) awaitHealthyAndUpdateNetworkInfo(ctx context.Context) er
|
||||
return err
|
||||
}
|
||||
|
||||
if err := lc.updateSubnetInfo(ctx); err != nil {
|
||||
if err := lc.updateChainInfo(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -725,7 +725,7 @@ func (lc *localNetwork) updateNodeInfo() error {
|
||||
|
||||
lc.nodeInfos = make(map[string]*rpcpb.NodeInfo)
|
||||
for name, node := range nodes {
|
||||
trackSubnets, err := node.GetFlag(config.TrackNetsKey)
|
||||
trackChains, err := node.GetFlag(config.TrackNetsKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -739,7 +739,7 @@ func (lc *localNetwork) updateNodeInfo() error {
|
||||
DbDir: node.GetDbDir(),
|
||||
Config: []byte(node.GetConfigFile()),
|
||||
PluginDir: node.GetPluginDir(),
|
||||
WhitelistedSubnets: trackSubnets,
|
||||
WhitelistedChains: trackChains,
|
||||
Paused: node.GetPaused(),
|
||||
}
|
||||
|
||||
|
||||
+123
-123
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package server implements server.
|
||||
package server
|
||||
@@ -70,9 +70,9 @@ var (
|
||||
ErrNodeNotFound = errors.New("node not found")
|
||||
ErrPeerNotFound = errors.New("peer not found")
|
||||
ErrStatusCanceled = errors.New("gRPC stream status canceled")
|
||||
ErrNoBlockchainSpec = errors.New("no blockchain spec was provided")
|
||||
ErrNoSubnetID = errors.New("subnetID is missing")
|
||||
ErrNoElasticSubnetSpec = errors.New("no elastic subnet spec was provided")
|
||||
ErrNoChainSpec = errors.New("no blockchain spec was provided")
|
||||
ErrNoChainID = errors.New("chainID is missing")
|
||||
ErrNoElasticChainSpec = errors.New("no elastic chain spec was provided")
|
||||
ErrNoValidatorSpec = errors.New("no validator spec was provided")
|
||||
)
|
||||
|
||||
@@ -285,11 +285,11 @@ func (s *server) Start(_ context.Context, req *rpcpb.StartRequest) (*rpcpb.Start
|
||||
}
|
||||
|
||||
pluginDir := req.GetPluginDir()
|
||||
chainSpecs := []network.BlockchainSpec{}
|
||||
chainSpecs := []network.ChainSpec{}
|
||||
if len(req.GetBlockchainSpecs()) > 0 {
|
||||
s.log.Info("plugin-dir:", zap.String("plugin-dir", pluginDir))
|
||||
for _, spec := range req.GetBlockchainSpecs() {
|
||||
chainSpec, err := getNetworkBlockchainSpec(s.log, spec, true, pluginDir)
|
||||
chainSpec, err := getNetworkChainSpec(s.log, spec, true, pluginDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -300,7 +300,7 @@ func (s *server) Start(_ context.Context, req *rpcpb.StartRequest) (*rpcpb.Start
|
||||
var (
|
||||
execPath = req.GetExecPath()
|
||||
numNodes = req.GetNumNodes()
|
||||
trackSubnets = req.GetWhitelistedSubnets()
|
||||
trackChains = req.GetWhitelistedChains()
|
||||
rootDataDir = req.GetRootDataDir()
|
||||
pid = int32(os.Getpid())
|
||||
globalNodeConfig = req.GetGlobalNodeConfig()
|
||||
@@ -335,14 +335,14 @@ func (s *server) Start(_ context.Context, req *rpcpb.StartRequest) (*rpcpb.Start
|
||||
execPath: execPath,
|
||||
rootDataDir: rootDataDir,
|
||||
numNodes: numNodes,
|
||||
trackSubnets: trackSubnets,
|
||||
trackChains: trackChains,
|
||||
redirectNodesOutput: s.cfg.RedirectNodesOutput,
|
||||
pluginDir: pluginDir,
|
||||
globalNodeConfig: globalNodeConfig,
|
||||
customNodeConfigs: customNodeConfigs,
|
||||
chainConfigs: req.ChainConfigs,
|
||||
upgradeConfigs: req.UpgradeConfigs,
|
||||
subnetConfigs: req.SubnetConfigs,
|
||||
pChainConfigs: req.ChainConfigFiles,
|
||||
logLevel: s.cfg.LogLevel,
|
||||
reassignPortsIfUsed: req.GetReassignPortsIfUsed(),
|
||||
dynamicPorts: req.GetDynamicPorts(),
|
||||
@@ -355,7 +355,7 @@ func (s *server) Start(_ context.Context, req *rpcpb.StartRequest) (*rpcpb.Start
|
||||
s.log.Info("starting",
|
||||
zap.String("exec-path", execPath),
|
||||
zap.Uint32("num-nodes", numNodes),
|
||||
zap.String("track-subnets", trackSubnets),
|
||||
zap.String("track-chains", trackChains),
|
||||
zap.Int32("pid", pid),
|
||||
zap.String("root-data-dir", rootDataDir),
|
||||
zap.String("plugin-dir", pluginDir),
|
||||
@@ -409,7 +409,7 @@ func (s *server) updateClusterInfo() {
|
||||
for chainID, chainInfo := range s.network.customChainIDToInfo {
|
||||
s.clusterInfo.CustomChains[chainID.String()] = chainInfo.info
|
||||
}
|
||||
s.clusterInfo.Subnets = s.network.subnets
|
||||
s.clusterInfo.Chains = s.network.chains
|
||||
}
|
||||
|
||||
// wait until some of this conditions is met:
|
||||
@@ -477,26 +477,26 @@ func (s *server) CreateBlockchains(
|
||||
s.log.Debug("CreateBlockchains")
|
||||
|
||||
if len(req.GetBlockchainSpecs()) == 0 {
|
||||
return nil, ErrNoBlockchainSpec
|
||||
return nil, ErrNoChainSpec
|
||||
}
|
||||
|
||||
chainSpecs := []network.BlockchainSpec{}
|
||||
chainSpecs := []network.ChainSpec{}
|
||||
for _, spec := range req.GetBlockchainSpecs() {
|
||||
chainSpec, err := getNetworkBlockchainSpec(s.log, spec, false, s.network.pluginDir)
|
||||
chainSpec, err := getNetworkChainSpec(s.log, spec, false, s.network.pluginDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chainSpecs = append(chainSpecs, chainSpec)
|
||||
}
|
||||
|
||||
// check that the given subnets exist
|
||||
subnetsSet := set.Set[string]{}
|
||||
subnetIDsList := maps.Keys(s.clusterInfo.Subnets)
|
||||
subnetsSet.Add(subnetIDsList...)
|
||||
// check that the given chains exist
|
||||
chainsSet := set.Set[string]{}
|
||||
chainIDsList := maps.Keys(s.clusterInfo.Chains)
|
||||
chainsSet.Add(chainIDsList...)
|
||||
|
||||
for _, chainSpec := range chainSpecs {
|
||||
if chainSpec.SubnetID != nil && !subnetsSet.Contains(*chainSpec.SubnetID) {
|
||||
return nil, fmt.Errorf("subnet id %q does not exits", *chainSpec.SubnetID)
|
||||
if chainSpec.ChainID != nil && !chainsSet.Contains(*chainSpec.ChainID) {
|
||||
return nil, fmt.Errorf("chain id %q does not exist", *chainSpec.ChainID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,15 +554,15 @@ func (s *server) AddPermissionlessValidator(
|
||||
validatorSpecList = append(validatorSpecList, validatorSpec)
|
||||
}
|
||||
|
||||
// check that the given subnets exist
|
||||
subnetsSet := set.Set[string]{}
|
||||
subnetsSet.Add(maps.Keys(s.clusterInfo.Subnets)...)
|
||||
// check that the given chains exist
|
||||
chainsSet := set.Set[string]{}
|
||||
chainsSet.Add(maps.Keys(s.clusterInfo.Chains)...)
|
||||
|
||||
for _, validatorSpec := range validatorSpecList {
|
||||
if validatorSpec.SubnetID == "" {
|
||||
return nil, ErrNoSubnetID
|
||||
} else if !subnetsSet.Contains(validatorSpec.SubnetID) {
|
||||
return nil, fmt.Errorf("subnet id %q does not exist", validatorSpec.SubnetID)
|
||||
if validatorSpec.ChainID == "" {
|
||||
return nil, ErrNoChainID
|
||||
} else if !chainsSet.Contains(validatorSpec.ChainID) {
|
||||
return nil, fmt.Errorf("chain id %q does not exist", validatorSpec.ChainID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,10 +589,10 @@ func (s *server) AddPermissionlessValidator(
|
||||
return &rpcpb.AddPermissionlessValidatorResponse{ClusterInfo: clusterInfo}, nil
|
||||
}
|
||||
|
||||
func (s *server) RemoveSubnetValidator(
|
||||
func (s *server) RemoveChainValidator(
|
||||
_ context.Context,
|
||||
req *rpcpb.RemoveSubnetValidatorRequest,
|
||||
) (*rpcpb.RemoveSubnetValidatorResponse, error) {
|
||||
req *rpcpb.RemoveChainValidatorRequest,
|
||||
) (*rpcpb.RemoveChainValidatorResponse, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
@@ -600,27 +600,27 @@ func (s *server) RemoveSubnetValidator(
|
||||
return nil, ErrNotBootstrapped
|
||||
}
|
||||
|
||||
s.log.Debug("RemoveSubnetValidator")
|
||||
s.log.Debug("RemoveChainValidator")
|
||||
|
||||
if len(req.GetValidatorSpec()) == 0 {
|
||||
return nil, ErrNoValidatorSpec
|
||||
}
|
||||
|
||||
validatorSpecList := []network.RemoveSubnetValidatorSpec{}
|
||||
validatorSpecList := []network.RemoveChainValidatorSpec{}
|
||||
for _, spec := range req.GetValidatorSpec() {
|
||||
validatorSpec := getRemoveSubnetValidatorSpec(spec)
|
||||
validatorSpec := getRemoveChainValidatorSpec(spec)
|
||||
validatorSpecList = append(validatorSpecList, validatorSpec)
|
||||
}
|
||||
|
||||
// check that the given subnets exist
|
||||
subnetsSet := set.Set[string]{}
|
||||
subnetsSet.Add(maps.Keys(s.clusterInfo.Subnets)...)
|
||||
// check that the given chains exist
|
||||
chainsSet := set.Set[string]{}
|
||||
chainsSet.Add(maps.Keys(s.clusterInfo.Chains)...)
|
||||
|
||||
for _, validatorSpec := range validatorSpecList {
|
||||
if validatorSpec.SubnetID == "" {
|
||||
return nil, ErrNoSubnetID
|
||||
} else if !subnetsSet.Contains(validatorSpec.SubnetID) {
|
||||
return nil, fmt.Errorf("subnet id %q does not exist", validatorSpec.SubnetID)
|
||||
if validatorSpec.ChainID == "" {
|
||||
return nil, ErrNoChainID
|
||||
} else if !chainsSet.Contains(validatorSpec.ChainID) {
|
||||
return nil, fmt.Errorf("chain id %q does not exist", validatorSpec.ChainID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,28 +629,28 @@ func (s *server) RemoveSubnetValidator(
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), waitForHealthyTimeout)
|
||||
defer cancel()
|
||||
err := s.network.RemoveSubnetValidator(ctx, validatorSpecList)
|
||||
err := s.network.RemoveChainValidator(ctx, validatorSpecList)
|
||||
|
||||
s.updateClusterInfo()
|
||||
|
||||
if err != nil {
|
||||
s.log.Error("failed to remove subnet validator", zap.Error(err))
|
||||
s.log.Error("failed to remove chain validator", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.log.Info("successfully removed subnet validator")
|
||||
s.log.Info("successfully removed chain validator")
|
||||
|
||||
clusterInfo, err := deepCopy(s.clusterInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rpcpb.RemoveSubnetValidatorResponse{ClusterInfo: clusterInfo}, nil
|
||||
return &rpcpb.RemoveChainValidatorResponse{ClusterInfo: clusterInfo}, nil
|
||||
}
|
||||
|
||||
func (s *server) TransformElasticSubnets(
|
||||
func (s *server) TransformElasticChains(
|
||||
_ context.Context,
|
||||
req *rpcpb.TransformElasticSubnetsRequest,
|
||||
) (*rpcpb.TransformElasticSubnetsResponse, error) {
|
||||
req *rpcpb.TransformElasticChainsRequest,
|
||||
) (*rpcpb.TransformElasticChainsResponse, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
@@ -658,27 +658,27 @@ func (s *server) TransformElasticSubnets(
|
||||
return nil, ErrNotBootstrapped
|
||||
}
|
||||
|
||||
s.log.Debug("TransformElasticSubnet")
|
||||
s.log.Debug("TransformElasticChain")
|
||||
|
||||
if len(req.GetElasticSubnetSpec()) == 0 {
|
||||
return nil, ErrNoElasticSubnetSpec
|
||||
if len(req.GetElasticChainSpec()) == 0 {
|
||||
return nil, ErrNoElasticChainSpec
|
||||
}
|
||||
|
||||
elasticSubnetSpecList := []network.ElasticSubnetSpec{}
|
||||
for _, spec := range req.GetElasticSubnetSpec() {
|
||||
elasticSubnetSpec := getNetworkElasticSubnetSpec(spec)
|
||||
elasticSubnetSpecList = append(elasticSubnetSpecList, elasticSubnetSpec)
|
||||
elasticParticipantsSpecList := []network.ElasticChainSpec{}
|
||||
for _, spec := range req.GetElasticChainSpec() {
|
||||
elasticParticipantsSpec := getNetworkElasticChainSpec(spec)
|
||||
elasticParticipantsSpecList = append(elasticParticipantsSpecList, elasticParticipantsSpec)
|
||||
}
|
||||
|
||||
// check that the given subnets exist
|
||||
subnetsSet := set.Set[string]{}
|
||||
subnetsSet.Add(maps.Keys(s.clusterInfo.Subnets)...)
|
||||
// check that the given chains exist
|
||||
chainsSet := set.Set[string]{}
|
||||
chainsSet.Add(maps.Keys(s.clusterInfo.Chains)...)
|
||||
|
||||
for _, elasticSubnetSpec := range elasticSubnetSpecList {
|
||||
if elasticSubnetSpec.SubnetID == nil {
|
||||
return nil, ErrNoSubnetID
|
||||
} else if !subnetsSet.Contains(*elasticSubnetSpec.SubnetID) {
|
||||
return nil, fmt.Errorf("subnet id %q does not exist", *elasticSubnetSpec.SubnetID)
|
||||
for _, elasticParticipantsSpec := range elasticParticipantsSpecList {
|
||||
if elasticParticipantsSpec.ChainID == nil {
|
||||
return nil, ErrNoChainID
|
||||
} else if !chainsSet.Contains(*elasticParticipantsSpec.ChainID) {
|
||||
return nil, fmt.Errorf("chain id %q does not exist", *elasticParticipantsSpec.ChainID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,16 +687,16 @@ func (s *server) TransformElasticSubnets(
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), waitForHealthyTimeout)
|
||||
defer cancel()
|
||||
txIDs, assetIDs, err := s.network.TransformSubnets(ctx, elasticSubnetSpecList)
|
||||
txIDs, assetIDs, err := s.network.TransformChains(ctx, elasticParticipantsSpecList)
|
||||
|
||||
s.updateClusterInfo()
|
||||
|
||||
if err != nil {
|
||||
s.log.Error("failed to transform subnet into elastic subnet", zap.Error(err))
|
||||
s.log.Error("failed to transform chain into elastic chain", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.log.Info("subnet transformed into elastic subnet")
|
||||
s.log.Info("chain transformed into elastic chain")
|
||||
|
||||
strTXIDs := []string{}
|
||||
for _, txID := range txIDs {
|
||||
@@ -712,10 +712,10 @@ func (s *server) TransformElasticSubnets(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rpcpb.TransformElasticSubnetsResponse{ClusterInfo: clusterInfo, TxIds: strTXIDs, AssetIds: strAssetIDs}, nil
|
||||
return &rpcpb.TransformElasticChainsResponse{ClusterInfo: clusterInfo, TxIds: strTXIDs, AssetIds: strAssetIDs}, nil
|
||||
}
|
||||
|
||||
func (s *server) CreateSubnets(_ context.Context, req *rpcpb.CreateSubnetsRequest) (*rpcpb.CreateSubnetsResponse, error) {
|
||||
func (s *server) CreateChains(_ context.Context, req *rpcpb.CreateChainsRequest) (*rpcpb.CreateChainsResponse, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
@@ -723,12 +723,12 @@ func (s *server) CreateSubnets(_ context.Context, req *rpcpb.CreateSubnetsReques
|
||||
return nil, ErrNotBootstrapped
|
||||
}
|
||||
|
||||
s.log.Debug("CreateSubnets", zap.Uint32("num-subnets", uint32(len(req.GetSubnetSpecs()))))
|
||||
s.log.Debug("CreateParticipantGroups", zap.Uint32("num-groups", uint32(len(req.GetChainSpecs()))))
|
||||
|
||||
subnetSpecs := []network.SubnetSpec{}
|
||||
for _, spec := range req.GetSubnetSpecs() {
|
||||
subnetSpec := getNetworkSubnetSpec(spec)
|
||||
subnetSpecs = append(subnetSpecs, subnetSpec)
|
||||
participantsSpecs := []network.ParticipantsSpec{}
|
||||
for _, spec := range req.GetChainSpecs() {
|
||||
participantsSpec := getNetworkParticipantsSpec(spec)
|
||||
participantsSpecs = append(participantsSpecs, participantsSpec)
|
||||
}
|
||||
|
||||
s.log.Info("waiting for local cluster readiness")
|
||||
@@ -738,26 +738,26 @@ func (s *server) CreateSubnets(_ context.Context, req *rpcpb.CreateSubnetsReques
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), waitForHealthyTimeout)
|
||||
defer cancel()
|
||||
subnetIDs, err := s.network.CreateSubnets(ctx, subnetSpecs)
|
||||
chainIDs, err := s.network.CreateParticipantGroups(ctx, participantsSpecs)
|
||||
if err != nil {
|
||||
s.log.Error("failed to create subnets", zap.Error(err))
|
||||
s.log.Error("failed to create chains", zap.Error(err))
|
||||
s.stopAndRemoveNetwork(err)
|
||||
return nil, err
|
||||
} else {
|
||||
s.updateClusterInfo()
|
||||
}
|
||||
s.log.Info("subnets created")
|
||||
s.log.Info("chains created")
|
||||
|
||||
strSubnetIDs := []string{}
|
||||
for _, subnetID := range subnetIDs {
|
||||
strSubnetIDs = append(strSubnetIDs, subnetID.String())
|
||||
strChainIDs := []string{}
|
||||
for _, chainID := range chainIDs {
|
||||
strChainIDs = append(strChainIDs, chainID.String())
|
||||
}
|
||||
|
||||
clusterInfo, err := deepCopy(s.clusterInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rpcpb.CreateSubnetsResponse{ClusterInfo: clusterInfo, SubnetIds: strSubnetIDs}, nil
|
||||
return &rpcpb.CreateChainsResponse{ClusterInfo: clusterInfo, ChainIds: strChainIDs}, nil
|
||||
}
|
||||
|
||||
func (s *server) Health(ctx context.Context, _ *rpcpb.HealthRequest) (*rpcpb.HealthResponse, error) {
|
||||
@@ -971,7 +971,7 @@ func (s *server) AddNode(_ context.Context, req *rpcpb.AddNodeRequest) (*rpcpb.A
|
||||
RedirectStderr: s.cfg.RedirectNodesOutput,
|
||||
ChainConfigFiles: req.ChainConfigs,
|
||||
UpgradeConfigFiles: req.UpgradeConfigs,
|
||||
SubnetConfigFiles: req.SubnetConfigs,
|
||||
PChainConfigFiles: req.ChainConfigFiles,
|
||||
}
|
||||
|
||||
if _, err := s.network.nw.AddNode(nodeConfig); err != nil {
|
||||
@@ -1037,10 +1037,10 @@ func (s *server) RestartNode(ctx context.Context, req *rpcpb.RestartNodeRequest)
|
||||
req.Name,
|
||||
req.GetExecPath(),
|
||||
req.GetPluginDir(),
|
||||
req.GetWhitelistedSubnets(),
|
||||
req.GetWhitelistedChains(),
|
||||
req.GetChainConfigs(),
|
||||
req.GetUpgradeConfigs(),
|
||||
req.GetSubnetConfigs(),
|
||||
req.GetChainConfigFiles(),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1278,7 +1278,7 @@ func (s *server) LoadSnapshot(_ context.Context, req *rpcpb.LoadSnapshotRequest)
|
||||
rootDataDir: rootDataDir,
|
||||
chainConfigs: req.ChainConfigs,
|
||||
upgradeConfigs: req.UpgradeConfigs,
|
||||
subnetConfigs: req.SubnetConfigs,
|
||||
pChainConfigs: req.ChainConfigFiles,
|
||||
globalNodeConfig: req.GetGlobalNodeConfig(),
|
||||
logLevel: s.cfg.LogLevel,
|
||||
reassignPortsIfUsed: req.GetReassignPortsIfUsed(),
|
||||
@@ -1404,14 +1404,14 @@ func isClientCanceled(ctxErr error, err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func getNetworkElasticSubnetSpec(
|
||||
spec *rpcpb.ElasticSubnetSpec,
|
||||
) network.ElasticSubnetSpec {
|
||||
func getNetworkElasticChainSpec(
|
||||
spec *rpcpb.ElasticChainSpec,
|
||||
) network.ElasticChainSpec {
|
||||
minStakeDuration := time.Duration(spec.MinStakeDuration) * time.Hour
|
||||
maxStakeDuration := time.Duration(spec.MaxStakeDuration) * time.Hour
|
||||
|
||||
elasticSubnetSpec := network.ElasticSubnetSpec{
|
||||
SubnetID: &spec.SubnetId,
|
||||
elasticParticipantsSpec := network.ElasticChainSpec{
|
||||
ChainID: &spec.ChainId,
|
||||
AssetName: spec.AssetName,
|
||||
AssetSymbol: spec.AssetSymbol,
|
||||
InitialSupply: spec.InitialSupply,
|
||||
@@ -1427,7 +1427,7 @@ func getNetworkElasticSubnetSpec(
|
||||
MaxValidatorWeightFactor: byte(spec.MaxValidatorWeightFactor),
|
||||
UptimeRequirement: spec.UptimeRequirement,
|
||||
}
|
||||
return elasticSubnetSpec
|
||||
return elasticParticipantsSpec
|
||||
}
|
||||
|
||||
func getPermissionlessValidatorSpec(
|
||||
@@ -1448,7 +1448,7 @@ func getPermissionlessValidatorSpec(
|
||||
stakeDuration := time.Duration(spec.StakeDuration) * time.Hour
|
||||
|
||||
validatorSpec := network.PermissionlessValidatorSpec{
|
||||
SubnetID: spec.SubnetId,
|
||||
ChainID: spec.ChainId,
|
||||
AssetID: spec.AssetId,
|
||||
NodeName: spec.NodeName,
|
||||
StakedAmount: spec.StakedTokenAmount,
|
||||
@@ -1458,24 +1458,24 @@ func getPermissionlessValidatorSpec(
|
||||
return validatorSpec, nil
|
||||
}
|
||||
|
||||
func getRemoveSubnetValidatorSpec(
|
||||
spec *rpcpb.RemoveSubnetValidatorSpec,
|
||||
) network.RemoveSubnetValidatorSpec {
|
||||
validatorSpec := network.RemoveSubnetValidatorSpec{
|
||||
SubnetID: spec.SubnetId,
|
||||
func getRemoveChainValidatorSpec(
|
||||
spec *rpcpb.RemoveChainValidatorSpec,
|
||||
) network.RemoveChainValidatorSpec {
|
||||
validatorSpec := network.RemoveChainValidatorSpec{
|
||||
ChainID: spec.ChainId,
|
||||
NodeNames: spec.GetNodeNames(),
|
||||
}
|
||||
return validatorSpec
|
||||
}
|
||||
|
||||
func getNetworkBlockchainSpec(
|
||||
func getNetworkChainSpec(
|
||||
log luxlog.Logger,
|
||||
spec *rpcpb.BlockchainSpec,
|
||||
isNewEmptyNetwork bool,
|
||||
pluginDir string,
|
||||
) (network.BlockchainSpec, error) {
|
||||
if isNewEmptyNetwork && spec.SubnetId != nil {
|
||||
return network.BlockchainSpec{}, errors.New("blockchain subnet id must be nil if starting a new empty network")
|
||||
) (network.ChainSpec, error) {
|
||||
if isNewEmptyNetwork && spec.ChainId != nil {
|
||||
return network.ChainSpec{}, errors.New("blockchain chain id must be nil if starting a new empty network")
|
||||
}
|
||||
|
||||
vmName := spec.VmName
|
||||
@@ -1483,7 +1483,7 @@ func getNetworkBlockchainSpec(
|
||||
vmID, err := utils.VMID(vmName)
|
||||
if err != nil {
|
||||
log.Warn("failed to convert VM name to VM ID", zap.String("vm-name", vmName), zap.Error(err))
|
||||
return network.BlockchainSpec{}, ErrInvalidVMName
|
||||
return network.ChainSpec{}, ErrInvalidVMName
|
||||
}
|
||||
|
||||
// there is no default plugindir from the ANR point of view, will not check if not given
|
||||
@@ -1491,7 +1491,7 @@ func getNetworkBlockchainSpec(
|
||||
if err := utils.CheckPluginPath(
|
||||
filepath.Join(pluginDir, vmID.String()),
|
||||
); err != nil {
|
||||
return network.BlockchainSpec{}, err
|
||||
return network.ChainSpec{}, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1507,9 +1507,9 @@ func getNetworkBlockchainSpec(
|
||||
networkUpgradeBytes = readFileOrString(spec.NetworkUpgrade)
|
||||
}
|
||||
|
||||
var subnetConfigBytes []byte
|
||||
if spec.SubnetSpec != nil && spec.SubnetSpec.SubnetConfig != "" {
|
||||
subnetConfigBytes = readFileOrString(spec.SubnetSpec.SubnetConfig)
|
||||
// Override chain config with ChainSpec.ChainConfigFile if provided
|
||||
if spec.ChainSpec != nil && spec.ChainSpec.ChainConfigFile != "" {
|
||||
chainConfigBytes = readFileOrString(spec.ChainSpec.ChainConfigFile)
|
||||
}
|
||||
|
||||
perNodeChainConfig := map[string][]byte{}
|
||||
@@ -1518,49 +1518,49 @@ func getNetworkBlockchainSpec(
|
||||
|
||||
perNodeChainConfigMap := map[string]interface{}{}
|
||||
if err := json.Unmarshal(perNodeChainConfigBytes, &perNodeChainConfigMap); err != nil {
|
||||
return network.BlockchainSpec{}, err
|
||||
return network.ChainSpec{}, err
|
||||
}
|
||||
|
||||
for nodeName, cfg := range perNodeChainConfigMap {
|
||||
cfgBytes, err := json.Marshal(cfg)
|
||||
if err != nil {
|
||||
return network.BlockchainSpec{}, err
|
||||
return network.ChainSpec{}, err
|
||||
}
|
||||
perNodeChainConfig[nodeName] = cfgBytes
|
||||
}
|
||||
}
|
||||
|
||||
blockchainSpec := network.BlockchainSpec{
|
||||
chainSpec := network.ChainSpec{
|
||||
VMName: vmName,
|
||||
Genesis: genesisBytes,
|
||||
ChainConfig: chainConfigBytes,
|
||||
NetworkUpgrade: networkUpgradeBytes,
|
||||
SubnetID: spec.SubnetId,
|
||||
BlockchainAlias: spec.BlockchainAlias,
|
||||
ChainID: spec.ChainId,
|
||||
Alias: spec.BlockchainAlias,
|
||||
PerNodeChainConfig: perNodeChainConfig,
|
||||
}
|
||||
|
||||
if spec.SubnetSpec != nil {
|
||||
subnetSpec := network.SubnetSpec{
|
||||
Participants: spec.SubnetSpec.Participants,
|
||||
SubnetConfig: subnetConfigBytes,
|
||||
if spec.ChainSpec != nil {
|
||||
participantsSpec := network.ParticipantsSpec{
|
||||
Participants: spec.ChainSpec.Participants,
|
||||
ChainConfig: chainConfigBytes,
|
||||
}
|
||||
blockchainSpec.SubnetSpec = &subnetSpec
|
||||
chainSpec.ParticipantsSpec = &participantsSpec
|
||||
}
|
||||
|
||||
return blockchainSpec, nil
|
||||
return chainSpec, nil
|
||||
}
|
||||
|
||||
func getNetworkSubnetSpec(
|
||||
spec *rpcpb.SubnetSpec,
|
||||
) network.SubnetSpec {
|
||||
var subnetConfigBytes []byte
|
||||
if spec.SubnetConfig != "" {
|
||||
subnetConfigBytes = readFileOrString(spec.SubnetConfig)
|
||||
func getNetworkParticipantsSpec(
|
||||
spec *rpcpb.ChainSpec,
|
||||
) network.ParticipantsSpec {
|
||||
var chainConfigBytes []byte
|
||||
if spec.ChainConfigFile != "" {
|
||||
chainConfigBytes = readFileOrString(spec.ChainConfigFile)
|
||||
}
|
||||
return network.SubnetSpec{
|
||||
return network.ParticipantsSpec{
|
||||
Participants: spec.Participants,
|
||||
SubnetConfig: subnetConfigBytes,
|
||||
ChainConfig: chainConfigBytes,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
name: lux-local
|
||||
version: 1.0.0
|
||||
description: Local Lux L1 for testing
|
||||
|
||||
engines:
|
||||
- name: lux-node-1
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9650
|
||||
staking_port: 9651
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
extra:
|
||||
dev-mode: true
|
||||
sybil-protection-disabled-weight: 100
|
||||
|
||||
networks:
|
||||
- name: lux-local
|
||||
type: l1
|
||||
engine: lux-node-1
|
||||
chain_id: 96369
|
||||
endpoints:
|
||||
- http://localhost:9650
|
||||
@@ -0,0 +1,60 @@
|
||||
name: lux-mainnet-5node
|
||||
version: 1.0.0
|
||||
description: 5-node Lux Mainnet local network
|
||||
|
||||
engines:
|
||||
- name: mainnet-node-1
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9650
|
||||
staking_port: 9651
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-5node/node1
|
||||
|
||||
- name: mainnet-node-2
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9660
|
||||
staking_port: 9661
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-5node/node2
|
||||
|
||||
- name: mainnet-node-3
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9670
|
||||
staking_port: 9671
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-5node/node3
|
||||
|
||||
- name: mainnet-node-4
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9680
|
||||
staking_port: 9681
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-5node/node4
|
||||
|
||||
- name: mainnet-node-5
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9690
|
||||
staking_port: 9691
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-5node/node5
|
||||
|
||||
networks:
|
||||
- name: lux-mainnet-local
|
||||
type: l1
|
||||
chain_id: 96369
|
||||
endpoints:
|
||||
- http://localhost:9650
|
||||
- http://localhost:9660
|
||||
- http://localhost:9670
|
||||
- http://localhost:9680
|
||||
- http://localhost:9690
|
||||
@@ -0,0 +1,60 @@
|
||||
name: lux-mainnet-alt
|
||||
version: 1.0.0
|
||||
description: 5-node Lux Mainnet on alternate ports (9640+) for parallel network operation
|
||||
|
||||
engines:
|
||||
- name: mainnet-alt-node-1
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9640
|
||||
staking_port: 9641
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-alt/node1
|
||||
|
||||
- name: mainnet-alt-node-2
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9642
|
||||
staking_port: 9643
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-alt/node2
|
||||
|
||||
- name: mainnet-alt-node-3
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9644
|
||||
staking_port: 9645
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-alt/node3
|
||||
|
||||
- name: mainnet-alt-node-4
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9646
|
||||
staking_port: 9647
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-alt/node4
|
||||
|
||||
- name: mainnet-alt-node-5
|
||||
type: lux
|
||||
network_id: 96369
|
||||
http_port: 9648
|
||||
staking_port: 9649
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-mainnet-alt/node5
|
||||
|
||||
networks:
|
||||
- name: lux-mainnet-alt
|
||||
type: l1
|
||||
chain_id: 96369
|
||||
endpoints:
|
||||
- http://localhost:9640
|
||||
- http://localhost:9642
|
||||
- http://localhost:9644
|
||||
- http://localhost:9646
|
||||
- http://localhost:9648
|
||||
@@ -0,0 +1,60 @@
|
||||
name: lux-testnet-5node
|
||||
version: 1.0.0
|
||||
description: 5-node Lux Testnet local network
|
||||
|
||||
engines:
|
||||
- name: testnet-node-1
|
||||
type: lux
|
||||
network_id: 96368
|
||||
http_port: 9750
|
||||
staking_port: 9751
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-testnet-5node/node1
|
||||
|
||||
- name: testnet-node-2
|
||||
type: lux
|
||||
network_id: 96368
|
||||
http_port: 9760
|
||||
staking_port: 9761
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-testnet-5node/node2
|
||||
|
||||
- name: testnet-node-3
|
||||
type: lux
|
||||
network_id: 96368
|
||||
http_port: 9770
|
||||
staking_port: 9771
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-testnet-5node/node3
|
||||
|
||||
- name: testnet-node-4
|
||||
type: lux
|
||||
network_id: 96368
|
||||
http_port: 9780
|
||||
staking_port: 9781
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-testnet-5node/node4
|
||||
|
||||
- name: testnet-node-5
|
||||
type: lux
|
||||
network_id: 96368
|
||||
http_port: 9790
|
||||
staking_port: 9791
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
data_dir: /tmp/lux-testnet-5node/node5
|
||||
|
||||
networks:
|
||||
- name: lux-testnet-local
|
||||
type: l1
|
||||
chain_id: 96368
|
||||
endpoints:
|
||||
- http://localhost:9750
|
||||
- http://localhost:9760
|
||||
- http://localhost:9770
|
||||
- http://localhost:9780
|
||||
- http://localhost:9790
|
||||
+72
-69
@@ -1,5 +1,8 @@
|
||||
//go:build e2e
|
||||
// +build e2e
|
||||
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// e2e implements the e2e tests.
|
||||
package e2e_test
|
||||
@@ -81,8 +84,8 @@ var (
|
||||
{"new_node1", "new_node2"},
|
||||
{"new_node3", "new_node4"},
|
||||
}
|
||||
testElasticSubnetConfig = rpcpb.ElasticSubnetSpec{
|
||||
SubnetId: "",
|
||||
testElasticChainConfig = rpcpb.ElasticChainSpec{
|
||||
ChainId: "",
|
||||
AssetName: "BLIZZARD",
|
||||
AssetSymbol: "BRRR",
|
||||
InitialSupply: 240000000,
|
||||
@@ -110,7 +113,7 @@ func init() {
|
||||
flag.StringVar(
|
||||
&logLevel,
|
||||
"log-level",
|
||||
logging.Info.String(),
|
||||
luxlog.Info.String(),
|
||||
"log level",
|
||||
)
|
||||
flag.StringVar(
|
||||
@@ -166,10 +169,10 @@ var _ = ginkgo.BeforeSuite(func() {
|
||||
logDir, err = utils.MkDirWithTimestamp(clientRootDir)
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
}
|
||||
lvl, err := logging.ToLevel(logLevel)
|
||||
lvl, err := luxlog.ToLevel(logLevel)
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
logFactory := logging.NewFactory(logging.Config{
|
||||
RotatingWriterConfig: logging.RotatingWriterConfig{
|
||||
logFactory := luxlog.NewFactory(luxlog.Config{
|
||||
RotatingWriterConfig: luxlog.RotatingWriterConfig{
|
||||
Directory: logDir,
|
||||
},
|
||||
DisplayLevel: lvl,
|
||||
@@ -191,13 +194,13 @@ var _ = ginkgo.BeforeSuite(func() {
|
||||
})
|
||||
|
||||
var _ = ginkgo.AfterSuite(func() {
|
||||
ux.Print(log, logging.Red.Wrap("shutting down cluster"))
|
||||
ux.Print(log, luxlog.Red.Wrap("shutting down cluster"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
_, err := cli.Stop(ctx)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
|
||||
ux.Print(log, logging.Red.Wrap("shutting down client"))
|
||||
ux.Print(log, luxlog.Red.Wrap("shutting down client"))
|
||||
err = cli.Close()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
})
|
||||
@@ -208,11 +211,11 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
createdBlockchainID := ""
|
||||
createdBlockchainID2 := ""
|
||||
ginkgo.By("start with blockchain specs", func() {
|
||||
ux.Print(log, logging.Green.Wrap("sending 'start' with the valid binary path: %s"), execPath1)
|
||||
ux.Print(log, luxlog.Green.Wrap("sending 'start' with the valid binary path: %s"), execPath1)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.Start(ctx, execPath1,
|
||||
client.WithPluginDir(filepath.Join(filepath.Dir(execPath1), "plugins")),
|
||||
client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{
|
||||
client.WithChainSpecs([]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
Genesis: genesisPath, // test genesis path usage
|
||||
@@ -223,13 +226,13 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
gomega.Ω(len(resp.ChainIds)).Should(gomega.Equal(1))
|
||||
createdBlockchainID = resp.ChainIds[0]
|
||||
ux.Print(log, logging.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
|
||||
ginkgo.By("can create a blockchain with a new subnet id", func() {
|
||||
ux.Print(log, logging.Blue.Wrap("can create a blockchain in a new subnet"))
|
||||
ux.Print(log, luxlog.Blue.Wrap("can create a blockchain in a new subnet"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.CreateBlockchains(ctx,
|
||||
resp, err := cli.CreateChains(ctx,
|
||||
[]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
@@ -267,9 +270,9 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
|
||||
ginkgo.By("can create a blockchain with an existing subnet id", func() {
|
||||
ux.Print(log, logging.Blue.Wrap("can create a blockchain in an existing subnet"))
|
||||
ux.Print(log, luxlog.Blue.Wrap("can create a blockchain in an existing subnet"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.CreateBlockchains(ctx,
|
||||
resp, err := cli.CreateChains(ctx,
|
||||
[]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
@@ -307,9 +310,9 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
|
||||
ginkgo.By("can create a blockchain with an existing subnet id loaded from snapshot", func() {
|
||||
ux.Print(log, logging.Blue.Wrap("can create a blockchain in an existing subnet"))
|
||||
ux.Print(log, luxlog.Blue.Wrap("can create a blockchain in an existing subnet"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
_, err := cli.CreateBlockchains(ctx,
|
||||
_, err := cli.CreateChains(ctx,
|
||||
[]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
@@ -323,14 +326,14 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
|
||||
ginkgo.By("can create a blockchain with new subnet id with some of existing participating nodes", func() {
|
||||
ux.Print(log, logging.Blue.Wrap("can create a blockchain with new subnet id with some of existing participating nodes"))
|
||||
ux.Print(log, luxlog.Blue.Wrap("can create a blockchain with new subnet id with some of existing participating nodes"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.CreateBlockchains(ctx,
|
||||
resp, err := cli.CreateChains(ctx,
|
||||
[]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
Genesis: genesisContents,
|
||||
SubnetSpec: &rpcpb.SubnetSpec{Participants: subnetParticipants},
|
||||
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: subnetParticipants},
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -355,14 +358,14 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
|
||||
ginkgo.By("can create a blockchain with new subnet id with some of existing participating nodes and a new node", func() {
|
||||
ux.Print(log, logging.Blue.Wrap("can create a blockchain new subnet id with some of existing participating nodes and a new node"))
|
||||
ux.Print(log, luxlog.Blue.Wrap("can create a blockchain new subnet id with some of existing participating nodes and a new node"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.CreateBlockchains(ctx,
|
||||
resp, err := cli.CreateChains(ctx,
|
||||
[]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
Genesis: genesisContents,
|
||||
SubnetSpec: &rpcpb.SubnetSpec{Participants: subnetParticipants2},
|
||||
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: subnetParticipants2},
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -389,7 +392,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
|
||||
ginkgo.By("can create two blockchains at a time", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.CreateBlockchains(ctx,
|
||||
resp, err := cli.CreateChains(ctx,
|
||||
[]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
@@ -416,17 +419,17 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
cancel()
|
||||
// create blockchains
|
||||
ctx, cancel = context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
resp, err := cli.CreateBlockchains(ctx,
|
||||
resp, err := cli.CreateChains(ctx,
|
||||
[]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
Genesis: genesisContents,
|
||||
SubnetSpec: &rpcpb.SubnetSpec{Participants: disjointNewSubnetParticipants[0]},
|
||||
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewSubnetParticipants[0]},
|
||||
},
|
||||
{
|
||||
VmName: "subnetevm",
|
||||
Genesis: genesisContents,
|
||||
SubnetSpec: &rpcpb.SubnetSpec{Participants: disjointNewSubnetParticipants[1]},
|
||||
ParticipantsSpec: &rpcpb.ParticipantsSpec{Participants: disjointNewSubnetParticipants[1]},
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -516,7 +519,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
_, err := cli.Start(ctx, execPath1,
|
||||
client.WithPluginDir(os.TempDir()),
|
||||
client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{
|
||||
client.WithChainSpecs([]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: "invalid",
|
||||
},
|
||||
@@ -535,7 +538,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
_, err = cli.Start(ctx, execPath1,
|
||||
client.WithPluginDir(filepath.Dir(filePath)),
|
||||
client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{
|
||||
client.WithChainSpecs([]*rpcpb.BlockchainSpec{
|
||||
{
|
||||
VmName: filepath.Base(filePath),
|
||||
},
|
||||
@@ -548,12 +551,12 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
|
||||
ginkgo.By("calling start API with the valid binary path", func() {
|
||||
ux.Print(log, logging.Green.Wrap("sending 'start' with the valid binary path: %s"), execPath1)
|
||||
ux.Print(log, luxlog.Green.Wrap("sending 'start' with the valid binary path: %s"), execPath1)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.Start(ctx, execPath1)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -569,7 +572,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
uris, err := cli.URIs(ctx)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Blue.Wrap("URIs: %s"), uris)
|
||||
ux.Print(log, luxlog.Blue.Wrap("URIs: %s"), uris)
|
||||
})
|
||||
|
||||
ginkgo.It("can fetch status", func() {
|
||||
@@ -589,7 +592,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
ch, err := cli.StreamStatus(ctx, 5*time.Second)
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
for info := range ch {
|
||||
ux.Print(log, logging.Green.Wrap("fetched info, node-names: %s"), info.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("fetched info, node-names: %s"), info.NodeNames)
|
||||
if info.Healthy {
|
||||
break
|
||||
}
|
||||
@@ -602,7 +605,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
resp, err := cli.RemoveNode(ctx, "node5")
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("successfully removed, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully removed, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -612,7 +615,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
resp, err := cli.RestartNode(ctx, "node4", client.WithExecPath(execPath2))
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("successfully restarted, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully restarted, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -625,10 +628,10 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
|
||||
v, ok := resp.ClusterInfo.AttachedPeerInfos["node1"]
|
||||
gomega.Ω(ok).Should(gomega.BeTrue())
|
||||
ux.Print(log, logging.Green.Wrap("successfully attached peer, peers: %+v"), v.Peers)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully attached peer, peers: %+v"), v.Peers)
|
||||
|
||||
mc, err := message.NewCreator(
|
||||
logging.NoLog{},
|
||||
luxlog.NoLog{},
|
||||
metrics.NewRegistry(),
|
||||
"",
|
||||
luxd_constants.DefaultNetworkCompressionType,
|
||||
@@ -656,38 +659,38 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
|
||||
ginkgo.It("can add a node", func() {
|
||||
ginkgo.By("calling AddNode", func() {
|
||||
ux.Print(log, logging.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ux.Print(log, luxlog.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
resp, err := cli.AddNode(ctx, newNodeName, execPath1)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
|
||||
ginkgo.By("calling AddNode with existing node name, should fail", func() {
|
||||
ux.Print(log, logging.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ux.Print(log, luxlog.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
resp, err := cli.AddNode(ctx, newNodeName, execPath1)
|
||||
cancel()
|
||||
gomega.Ω(err.Error()).Should(gomega.ContainSubstring("repeated node name"))
|
||||
gomega.Ω(resp).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("'add-node' failed as expected"))
|
||||
ux.Print(log, luxlog.Green.Wrap("'add-node' failed as expected"))
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It("can start with custom config", func() {
|
||||
ginkgo.By("stopping network first", func() {
|
||||
ux.Print(log, logging.Red.Wrap("shutting down cluster"))
|
||||
ux.Print(log, luxlog.Red.Wrap("shutting down cluster"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
_, err := cli.Stop(ctx)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
|
||||
ux.Print(log, logging.Red.Wrap("shutting down client"))
|
||||
ux.Print(log, luxlog.Red.Wrap("shutting down client"))
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
})
|
||||
ginkgo.By("calling start API with custom config", func() {
|
||||
ux.Print(log, logging.Green.Wrap("sending 'start' with the valid binary path: %s"), execPath1)
|
||||
ux.Print(log, luxlog.Green.Wrap("sending 'start' with the valid binary path: %s"), execPath1)
|
||||
opts := []client.OpOption{
|
||||
client.WithNumNodes(numNodes),
|
||||
client.WithCustomNodeConfigs(customNodeConfigs),
|
||||
@@ -696,7 +699,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
resp, err := cli.Start(ctx, execPath1, opts...)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
ginkgo.By("can wait for health", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
@@ -705,15 +708,15 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
})
|
||||
ginkgo.By("overrides num-nodes", func() {
|
||||
ux.Print(log, logging.Green.Wrap("checking that given num-nodes %d have been overridden by custom configs: %d"), numNodes, len(customNodeConfigs))
|
||||
ux.Print(log, luxlog.Green.Wrap("checking that given num-nodes %d have been overridden by custom configs: %d"), numNodes, len(customNodeConfigs))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
uris, err := cli.URIs(ctx)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
gomega.Ω(uris).Should(gomega.HaveLen(len(customNodeConfigs)))
|
||||
ux.Print(log, logging.Green.Wrap("expected number of nodes up: %d"), len(customNodeConfigs))
|
||||
ux.Print(log, luxlog.Green.Wrap("expected number of nodes up: %d"), len(customNodeConfigs))
|
||||
|
||||
ux.Print(log, logging.Green.Wrap("checking correct admin APIs are enabled resp. disabled"))
|
||||
ux.Print(log, luxlog.Green.Wrap("checking correct admin APIs are enabled resp. disabled"))
|
||||
// we have 7 nodes, 3 have the admin API enabled, the other 4 disabled
|
||||
// therefore we expect exactly 4 calls to fail and exactly 3 to succeed.
|
||||
ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second)
|
||||
@@ -752,12 +755,12 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
ginkgo.It("can pause a node", func() {
|
||||
ginkgo.By("calling PauseNode", func() {
|
||||
ux.Print(log, logging.Green.Wrap("calling 'pause-node'"))
|
||||
ux.Print(log, luxlog.Green.Wrap("calling 'pause-node'"))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
resp, err := cli.PauseNode(ctx, pausedNodeName)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("successfully paused, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully paused, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
ginkgo.By("can wait for health", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
@@ -777,7 +780,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
resp, err := cli.ResumeNode(ctx, pausedNodeName)
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("successfully resumed %s, cluster node-names: %s"), "node1", resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully resumed %s, cluster node-names: %s"), "node1", resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
ginkgo.By("can wait for health", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
@@ -796,7 +799,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
|
||||
ginkgo.It("can add primary validator with BLS Keys", func() {
|
||||
ginkgo.By("calling AddNode", func() {
|
||||
ux.Print(log, logging.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ux.Print(log, luxlog.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
resp, err := cli.AddNode(ctx, newNodeName2, execPath1)
|
||||
cancel()
|
||||
@@ -806,7 +809,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
newNode2NodeID = nodeInfo.Id
|
||||
}
|
||||
}
|
||||
ux.Print(log, logging.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
ux.Print(log, luxlog.Green.Wrap("successfully started, node-names: %s"), resp.ClusterInfo.NodeNames)
|
||||
})
|
||||
ginkgo.By("can wait for health", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
@@ -816,7 +819,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
ginkgo.By("add 1 subnet", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.CreateSubnets(ctx, []*rpcpb.SubnetSpec{{}})
|
||||
resp, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{}})
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
gomega.Ω(len(resp.SubnetIds)).Should(gomega.Equal(1))
|
||||
@@ -847,7 +850,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
ginkgo.It("subnet creation", func() {
|
||||
ginkgo.By("add 1 subnet", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
_, err := cli.CreateSubnets(ctx, []*rpcpb.SubnetSpec{{}})
|
||||
_, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{}})
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
})
|
||||
@@ -861,7 +864,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
ginkgo.By("add 1 subnet with participants", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
response, err := cli.CreateSubnets(ctx, []*rpcpb.SubnetSpec{{Participants: subnetParticipants}})
|
||||
response, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{Participants: subnetParticipants}})
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
gomega.Ω(len(response.SubnetIds)).Should(gomega.Equal(1))
|
||||
@@ -877,7 +880,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
})
|
||||
ginkgo.By("add 1 subnet with node not currently added", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
response, err := cli.CreateSubnets(ctx, []*rpcpb.SubnetSpec{{Participants: subnetParticipants2}})
|
||||
response, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{Participants: subnetParticipants2}})
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
// verify that a new node is added to cluster
|
||||
@@ -888,13 +891,13 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
newSubnetID = response.SubnetIds[0]
|
||||
})
|
||||
ginkgo.By("calling AddNode with existing node name, should fail", func() {
|
||||
ux.Print(log, logging.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ux.Print(log, luxlog.Green.Wrap("calling 'add-node' with the valid binary path: %s"), execPath1)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
resp, err := cli.AddNode(ctx, newParticipantNode, execPath1)
|
||||
cancel()
|
||||
gomega.Ω(err.Error()).Should(gomega.ContainSubstring("repeated node name"))
|
||||
gomega.Ω(resp).Should(gomega.BeNil())
|
||||
ux.Print(log, logging.Green.Wrap("'add-node' failed as expected"))
|
||||
ux.Print(log, luxlog.Green.Wrap("'add-node' failed as expected"))
|
||||
})
|
||||
ginkgo.By("verify the newer subnet also has correct participants", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
@@ -910,11 +913,11 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
ginkgo.By("removing a subnet validator", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
defer cancel()
|
||||
testRemoveSubnetValidatorConfig := rpcpb.RemoveSubnetValidatorSpec{
|
||||
testRemoveSubnetValidatorConfig := rpcpb.RemoveChainValidatorSpec{
|
||||
NodeNames: []string{"node2"},
|
||||
SubnetId: newSubnetID,
|
||||
}
|
||||
_, err := cli.RemoveSubnetValidator(ctx, []*rpcpb.RemoveSubnetValidatorSpec{&testRemoveSubnetValidatorConfig})
|
||||
_, err := cli.RemoveSubnetValidator(ctx, []*rpcpb.RemoveChainValidatorSpec{&testRemoveSubnetValidatorConfig})
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
})
|
||||
ginkgo.By("verify there are only two validators left for subnet", func() {
|
||||
@@ -940,7 +943,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
var elasticSubnetID string
|
||||
ginkgo.By("add 1 subnet", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
resp, err := cli.CreateSubnets(ctx, []*rpcpb.SubnetSpec{{}})
|
||||
resp, err := cli.CreateParticipantGroups(ctx, []*rpcpb.ParticipantsSpec{{}})
|
||||
cancel()
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
gomega.Ω(len(resp.SubnetIds)).Should(gomega.Equal(1))
|
||||
@@ -954,13 +957,13 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
subnetInfo := status.ClusterInfo.Subnets[createdSubnetID]
|
||||
gomega.Ω(subnetInfo.IsElastic).Should(gomega.Equal(false))
|
||||
gomega.Ω(subnetInfo.ElasticSubnetId).Should(gomega.Equal(ids.Empty.String()))
|
||||
gomega.Ω(subnetInfo.ElasticChainId).Should(gomega.Equal(ids.Empty.String()))
|
||||
})
|
||||
ginkgo.By("transform 1 subnet to elastic subnet", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
defer cancel()
|
||||
testElasticSubnetConfig.SubnetId = createdSubnetID
|
||||
response, err := cli.TransformElasticSubnets(ctx, []*rpcpb.ElasticSubnetSpec{&testElasticSubnetConfig})
|
||||
response, err := cli.TransformElasticSubnets(ctx, []*rpcpb.ElasticParticipantsSpec{&testElasticSubnetConfig})
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
gomega.Ω(len(response.TxIds)).Should(gomega.Equal(1))
|
||||
gomega.Ω(len(response.AssetIds)).Should(gomega.Equal(1))
|
||||
@@ -973,14 +976,14 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
subnetInfo := status.ClusterInfo.Subnets[createdSubnetID]
|
||||
gomega.Ω(subnetInfo.IsElastic).Should(gomega.Equal(true))
|
||||
gomega.Ω(subnetInfo.ElasticSubnetId).ShouldNot(gomega.Equal(ids.Empty.String()))
|
||||
elasticSubnetID = subnetInfo.ElasticSubnetId
|
||||
gomega.Ω(subnetInfo.ElasticChainId).ShouldNot(gomega.Equal(ids.Empty.String()))
|
||||
elasticSubnetID = subnetInfo.ElasticChainId
|
||||
})
|
||||
ginkgo.By("transforming a subnet with same subnetID to elastic subnet will fail", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
defer cancel()
|
||||
testElasticSubnetConfig.SubnetId = createdSubnetID
|
||||
_, err := cli.TransformElasticSubnets(ctx, []*rpcpb.ElasticSubnetSpec{&testElasticSubnetConfig})
|
||||
_, err := cli.TransformElasticSubnets(ctx, []*rpcpb.ElasticParticipantsSpec{&testElasticSubnetConfig})
|
||||
gomega.Ω(err).Should(gomega.HaveOccurred())
|
||||
})
|
||||
ginkgo.By("save snapshot with elastic info", func() {
|
||||
@@ -1002,7 +1005,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
|
||||
gomega.Ω(err).Should(gomega.BeNil())
|
||||
subnetInfo := status.ClusterInfo.Subnets[createdSubnetID]
|
||||
gomega.Ω(subnetInfo.IsElastic).Should(gomega.Equal(true))
|
||||
gomega.Ω(subnetInfo.ElasticSubnetId).Should(gomega.Equal(elasticSubnetID))
|
||||
gomega.Ω(subnetInfo.ElasticChainId).Should(gomega.Equal(elasticSubnetID))
|
||||
})
|
||||
ginkgo.By("remove snapshot with elastic info", func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
package constants
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package utils
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Set k=v in JSON string
|
||||
// e.g., "track-subnets" is the key and value is "a,b,c".
|
||||
// e.g., "track-chains" is the key and value is "a,b,c".
|
||||
func SetJSONKey(jsonBody string, k string, v string) (string, error) {
|
||||
var config map[string]interface{}
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package utils
|
||||
|
||||
|
||||
+11
-11
@@ -97,34 +97,34 @@ func MkDirWithTimestamp(dirPrefix string) (string, error) {
|
||||
return dirName, os.MkdirAll(dirName, os.ModePerm)
|
||||
}
|
||||
|
||||
func VerifySubnetHasCorrectParticipants(
|
||||
func VerifyChainHasCorrectParticipants(
|
||||
log luxlog.Logger,
|
||||
subnetParticipants []string,
|
||||
chainParticipants []string,
|
||||
cluster *rpcb.ClusterInfo,
|
||||
subnetID string,
|
||||
chainID string,
|
||||
) bool {
|
||||
if cluster != nil {
|
||||
participatingNodeNames := cluster.Subnets[subnetID].GetSubnetParticipants().GetNodeNames()
|
||||
participatingNodeNames := cluster.Chains[chainID].GetChainParticipants().GetNodeNames()
|
||||
|
||||
var nodeIsInList bool
|
||||
// Check that all subnet validators are equal to the node IDs added as participant in subnet creation
|
||||
for _, node := range subnetParticipants {
|
||||
// Check that all chain validators are equal to the node IDs added as participant in chain creation
|
||||
for _, node := range chainParticipants {
|
||||
nodeIsInList = false
|
||||
for _, subnetValidator := range participatingNodeNames {
|
||||
if subnetValidator == node {
|
||||
for _, chainValidator := range participatingNodeNames {
|
||||
if chainValidator == node {
|
||||
nodeIsInList = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !nodeIsInList {
|
||||
ux.Print(log, luxlog.Red.Wrap(fmt.Sprintf("VerifySubnetHasCorrectParticipants: %#v", cluster)))
|
||||
ux.Print(log, luxlog.Red.Wrap(fmt.Sprintf("VerifySubnetHasCorrectParticipants: node not in list subnet %q node %q %v %v", subnetID, node, subnetParticipants, participatingNodeNames)))
|
||||
ux.Print(log, "%s", luxlog.Red.Wrap(fmt.Sprintf("VerifyChainHasCorrectParticipants: %#v", cluster)))
|
||||
ux.Print(log, "%s", luxlog.Red.Wrap(fmt.Sprintf("VerifyChainHasCorrectParticipants: node not in list chain %q node %q %v %v", chainID, node, chainParticipants, participatingNodeNames)))
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
ux.Print(log, luxlog.Red.Wrap("VerifySubnetHasCorrectParticipants: cluster is nil"))
|
||||
ux.Print(log, "%s", luxlog.Red.Wrap("VerifyChainHasCorrectParticipants: cluster is nil"))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
package ux
|
||||
|
||||
import (
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
luxlog "github.com/luxfi/log"
|
||||
)
|
||||
|
||||
//nolint:govet // msg is intentionally a format string that may come from variables
|
||||
func Print(log luxlog.Logger, msg string, args ...interface{}) {
|
||||
fmtMsg := fmt.Sprintf(msg, args...)
|
||||
log.Info(fmtMsg)
|
||||
|
||||
Reference in New Issue
Block a user