Skip to content

Commit

Permalink
Merge branch 'node-local-start-localnetwork' of github.com:ava-labs/a…
Browse files Browse the repository at this point in the history
…valanche-cli into node-local-start-localnetwork
  • Loading branch information
sukantoraymond committed Dec 9, 2024
2 parents b768508 + 065fa20 commit 787e680
Show file tree
Hide file tree
Showing 12 changed files with 562 additions and 71 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
"\\[Etna Subnet SOV\\]",
"\\[Etna AddRemove Validator SOV PoA\\]",
"\\[Etna AddRemove Validator SOV PoS\\]",
"\\[Etna Add Validator SOV Local\\]",
"\\[Subnet\\]",
"\\[Upgrade expect network failure\\]",
"\\[Upgrade public network\\]",
Expand All @@ -51,6 +52,8 @@ jobs:
suite: "\\[Etna AddRemove Validator SOV PoA\\]"
- os: ubuntu-latest
suite: "\\[Etna AddRemove Validator SOV PoS\\]"
- os: ubuntu-latest
suite: "\\[Etna Add Validator SOV Local\\]"
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down
116 changes: 100 additions & 16 deletions cmd/blockchaincmd/add_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
package blockchaincmd

import (
"encoding/hex"
"errors"
"fmt"
"math/big"
"time"

"github.com/ava-labs/avalanchego/config"
"github.com/ava-labs/avalanchego/utils/units"

"github.com/ava-labs/avalanchego/api/info"
"github.com/ethereum/go-ethereum/common"

"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
Expand All @@ -20,6 +19,7 @@ import (
"github.com/ava-labs/avalanche-cli/pkg/keychain"
"github.com/ava-labs/avalanche-cli/pkg/models"
"github.com/ava-labs/avalanche-cli/pkg/networkoptions"
"github.com/ava-labs/avalanche-cli/pkg/node"
"github.com/ava-labs/avalanche-cli/pkg/prompts"
"github.com/ava-labs/avalanche-cli/pkg/subnet"
"github.com/ava-labs/avalanche-cli/pkg/txutils"
Expand Down Expand Up @@ -70,6 +70,8 @@ var (
ErrNotPermissionedSubnet = errors.New("subnet is not permissioned")
aggregatorExtraEndpoints []string
clusterNameFlagValue string

createLocalValidator bool
)

// avalanche blockchain addValidator
Expand Down Expand Up @@ -101,6 +103,8 @@ Testnet or Mainnet.`,
cmd.Flags().StringVar(&pop, "bls-proof-of-possession", "", "set the BLS proof of possession of the validator to add")
cmd.Flags().StringVar(&remainingBalanceOwnerAddr, "remaining-balance-owner", "", "P-Chain address that will receive any leftover AVAX from the validator when it is removed from Subnet")
cmd.Flags().StringVar(&disableOwnerAddr, "disable-owner", "", "P-Chain address that will able to disable the validator with a P-Chain transaction")
cmd.Flags().BoolVar(&createLocalValidator, "create-local-validator", false, "create additional local validator and add it to existing running local node")
cmd.Flags().BoolVar(&partialSync, "partial-sync", true, "set primary network partial sync for new validators")
cmd.Flags().StringVar(&nodeEndpoint, "node-endpoint", "", "gather node id/bls from publicly available avalanchego apis on the given endpoint")
cmd.Flags().StringSliceVar(&aggregatorExtraEndpoints, "aggregator-extra-endpoints", nil, "endpoints for extra nodes that are needed in signature aggregation")
privateKeyFlags.AddToCmd(cmd, "to pay fees for completing the validator's registration (blockchain gas token)")
Expand All @@ -120,6 +124,20 @@ Testnet or Mainnet.`,
return cmd
}

func preAddChecks(network models.Network, sovereign bool) error {
if sovereign && network.Kind == models.Mainnet {
return errNotSupportedOnMainnet
}
if nodeEndpoint != "" && createLocalValidator {
return fmt.Errorf("cannot set both --node-endpoint and --create-local-validator")
}
if createLocalValidator && (nodeIDStr != "" || publicKey != "" || pop != "") {
return fmt.Errorf("cannot set --node-id, --bls-public-key or --bls-proof-of-possession if --create-local-validator used")
}

return nil
}

func addValidator(_ *cobra.Command, args []string) error {
blockchainName := args[0]
_, err := ValidateSubnetNameAndGetChains([]string{blockchainName})
Expand Down Expand Up @@ -151,6 +169,10 @@ func addValidator(_ *cobra.Command, args []string) error {
network = models.ConvertClusterToNetwork(network)
}

if err := preAddChecks(network, sc.Sovereign); err != nil {
return err
}

if sc.Networks[network.Name()].ClusterName != "" {
clusterNameFlagValue = sc.Networks[network.Name()].ClusterName
}
Expand All @@ -170,18 +192,87 @@ func addValidator(_ *cobra.Command, args []string) error {
return err
}

sovereign := sc.Sovereign

if nodeEndpoint != "" {
infoClient := info.NewClient(nodeEndpoint)
ctx, cancel := utils.GetAPILargeContext()
defer cancel()
nodeID, proofOfPossession, err := infoClient.GetNodeID(ctx)
nodeIDStr, publicKey, pop, err = node.GetNodeData(nodeEndpoint)
if err != nil {
return err
}
nodeIDStr = nodeID.String()
publicKey = "0x" + hex.EncodeToString(proofOfPossession.PublicKey[:])
pop = "0x" + hex.EncodeToString(proofOfPossession.ProofOfPossession[:])
}

// if we don't have a nodeID or ProofOfPossession by this point, prompt user if we want to add a aditional local node
if (!sovereign && nodeIDStr == "") || (sovereign && !createLocalValidator && nodeIDStr == "" && publicKey == "" && pop == "") {
for {
local := "Use my local machine to spin up an additional validator"
existing := "I have an existing Avalanche node (we will require its NodeID and BLS info)"
if option, err := app.Prompt.CaptureList(
"How would you like to set up the new validator",
[]string{local, existing},
); err != nil {
return err
} else {
createLocalValidator = option == local
break
}
}
}

// if user chose to upsize a local node to add another local validator
if createLocalValidator {
anrSettings := node.ANRSettings{}
nodeConfig := map[string]interface{}{}
ux.Logger.PrintToUser("Creating a new Avalanche node on local machine to add as a new validator to blockchain %s", blockchainName)
if app.AvagoNodeConfigExists(blockchainName) {
nodeConfig, err = utils.ReadJSON(app.GetAvagoNodeConfigPath(blockchainName))
if err != nil {
return err
}
}
if partialSync {
nodeConfig[config.PartialSyncPrimaryNetworkKey] = true
}
avalancheGoBinPath, err := node.GetLocalNodeAvalancheGoBinPath()
if err != nil {
return fmt.Errorf("failed to get local node avalanche go bin path: %w", err)
}

nodeName := ""
blockchainID := sc.Networks[network.Name()].BlockchainID
subnetID := sc.Networks[network.Name()].SubnetID

if nodeName, err = node.UpsizeLocalNode(
app,
network,
blockchainName,
blockchainID,
subnetID,
avalancheGoBinPath,
nodeConfig,
anrSettings,
); err != nil {
return err
}
// get node data
nodeInfo, err := node.GetNodeInfo(nodeName)
if err != nil {
return err
}
nodeIDStr, publicKey, pop, err = node.GetNodeData(nodeInfo.Uri)
if err != nil {
return err
}
// update sidecar with new node
if err := node.AddNodeInfoToSidecar(&sc, nodeInfo, network); err != nil {
return err
}
if err := app.UpdateSidecar(&sc); err != nil {
return err
}
// make sure extra validator endpoint added for the new node
aggregatorExtraEndpoints = append(aggregatorExtraEndpoints, constants.LocalAPIEndpoint)
}

if nodeIDStr == "" {
nodeID, err := PromptNodeID("add as a blockchain validator")
if err != nil {
Expand All @@ -192,13 +283,6 @@ func addValidator(_ *cobra.Command, args []string) error {
if err := prompts.ValidateNodeID(nodeIDStr); err != nil {
return err
}

sovereign := sc.Sovereign

if sovereign && network.Kind == models.Mainnet {
return errNotSupportedOnMainnet
}

if sovereign && publicKey == "" && pop == "" {
publicKey, pop, err = promptProofOfPossession(true, true)
if err != nil {
Expand Down
5 changes: 4 additions & 1 deletion cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
validatorManagerSDK "github.com/ava-labs/avalanche-cli/sdk/validatormanager"

"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/config"
"github.com/ava-labs/avalanchego/network/peer"

"github.com/ava-labs/avalanche-cli/cmd/interchaincmd/relayercmd"
Expand Down Expand Up @@ -680,6 +681,9 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
return err
}
}
if partialSync {
nodeConfig[config.PartialSyncPrimaryNetworkKey] = true
}
if network.Kind == models.Fuji {
globalNetworkFlags.UseFuji = true
}
Expand All @@ -690,7 +694,6 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
useEtnaDevnet,
avagoBinaryPath,
uint32(numLocalNodes),
partialSync,
nodeConfig,
anrSettings,
avagoVersionSettings,
Expand Down
12 changes: 6 additions & 6 deletions cmd/nodecmd/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/ava-labs/avalanche-cli/pkg/node"
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanchego/config"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -161,24 +162,23 @@ func localStartNode(_ *cobra.Command, args []string) error {
UseLatestAvalanchegoPreReleaseVersion: useLatestAvalanchegoPreReleaseVersion,
UseLatestAvalanchegoReleaseVersion: useLatestAvalanchegoReleaseVersion,
}
var (
err error
nodeConfig map[string]interface{}
)
nodeConfig := make(map[string]interface{})
if nodeConfigPath != "" {
var err error
nodeConfig, err = utils.ReadJSON(nodeConfigPath)
if err != nil {
return err
}
}

if partialSync {
nodeConfig[config.PartialSyncPrimaryNetworkKey] = true
}
return node.StartLocalNode(
app,
clusterName,
globalNetworkFlags.UseEtnaDevnet,
avalanchegoBinaryPath,
numNodes,
partialSync,
nodeConfig,
anrSettings,
avaGoVersionSetting,
Expand Down
Loading

0 comments on commit 787e680

Please sign in to comment.