Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate local machine into subnet deploy #2235

Closed
wants to merge 14 commits into from
131 changes: 82 additions & 49 deletions cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"strings"
"time"

"github.com/ava-labs/avalanche-cli/pkg/node"

"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/vms/platformvm/warp/message"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -464,6 +466,18 @@
return PrintSubnetInfo(blockchainName, true)
}

ux.Logger.PrintToUser("You can use your local machine as a bootstrap validator on the blockchain")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this to be guarded by a flag

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed

ux.Logger.PrintToUser("This means that you don't have to to set up a remote server on a cloud service (e.g. AWS / GCP) to be a validator on the blockchain.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably we want to explain more here? like this is temporary bootstrap validator

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not temporary if user wants to leave it the node indefinitely as validator


useLocalMachine, err := app.Prompt.CaptureYesNo("Do you want to use your local machine as a bootstrap validator?")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flag to avoid question for this and just proceed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed

if err != nil {
return err
}

if useLocalMachine {
bootstrapEndpoints = []string{"http://127.0.0.1:9650"}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might be tricky to assume this endpoint as port can be not 9650 but rather dynamic
cc @felipemadero

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should ask user for the endpoint and not yes/no for local machine.
we can hint that it can be 127.0.0.1:9650 for the local machine

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see now. After the previous question, a Start should be made and from that, the endpoint
can be obtained from the anr itself, not need to assume anything.
This is not related to the flag useLocalMachine. This relates to the local cluster that exists previous
to the deploy. The best way should be to check the network, which should be a local cluster,
in that case take the endpoint from anr.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably for another PR. Make an issue for this and keep current static assignment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

if len(bootstrapEndpoints) > 0 {
var changeAddr string
for _, endpoint := range bootstrapEndpoints {
Expand Down Expand Up @@ -663,7 +677,7 @@
}
deployer.CleanCacheWallet()
managerAddress := common.HexToAddress(validatormanager.ValidatorContractAddress)
isFullySigned, ConvertL1TxID, tx, remainingSubnetAuthKeys, err := deployer.ConvertL1(

Check warning on line 680 in cmd/blockchaincmd/deploy.go

View workflow job for this annotation

GitHub Actions / Lint

unexported-naming: the symbol ConvertL1TxID is local, its name should start with a lowercase letter (revive)
controlKeys,
subnetAuthKeys,
subnetID,
Expand Down Expand Up @@ -725,65 +739,84 @@
return err
}

if false {
chainSpec := contract.ChainSpec{
BlockchainName: blockchainName,
}
genesisAddress, genesisPrivateKey, err := contract.GetEVMSubnetPrefundedKey(
app,
network,
chainSpec,
)
if err != nil {
clusterName, err := node.GetClusterNameFromList(app)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cluster name to be taken from the input network itself IMO

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which should be a cluster

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

models.Networks has ClusterName

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to do it when integrating local node start

if err != nil {
return err
}

if !useLocalMachine {
if err = node.SyncSubnet(app, clusterName, blockchainName, true, nil); err != nil {
return err
}
privateKey, err := privateKeyFlags.GetPrivateKey(app, genesisPrivateKey)
if err != nil {
if err := node.WaitForHealthyCluster(app, clusterName, node.HealthCheckTimeout, node.HealthCheckPoolTime); err != nil {
return err
}
if privateKey == "" {
privateKey, err = prompts.PromptPrivateKey(
app.Prompt,
"Which key to you want to use to pay for initializing Validator Manager contract? (Uses Blockchain gas token)",
app.GetKeyDir(),
app.GetKey,
genesisAddress,
genesisPrivateKey,
)
if err != nil {
return err
}
}
rpcURL, _, err := contract.GetBlockchainEndpoints(
app,
network,
chainSpec,
true,
false,
)
if err != nil {
} else {
if err := node.TrackSubnetWithLocalMachine(app, clusterName, blockchainName); err != nil {
return err
}
aggregatorExtraPeerEndpoints, err := GetAggregatorExtraPeerEndpoints(network)

// TODO: replace wait below wiht check for healhty in local machine
time.Sleep(70 * time.Second)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will have to change this

}

chainSpec := contract.ChainSpec{
BlockchainName: blockchainName,
}
genesisAddress, genesisPrivateKey, err := contract.GetEVMSubnetPrefundedKey(
app,
network,
chainSpec,
)
if err != nil {
return err
}
privateKey, err := privateKeyFlags.GetPrivateKey(app, genesisPrivateKey)
if err != nil {
return err
}
if privateKey == "" {
privateKey, err = prompts.PromptPrivateKey(
app.Prompt,
"Which key to you want to use to pay for initializing Validator Manager contract? (Uses Blockchain gas token)",
app.GetKeyDir(),
app.GetKey,
genesisAddress,
genesisPrivateKey,
)
if err != nil {
return err
}
if err := validatormanager.SetupPoA(
app,
network,
rpcURL,
contract.ChainSpec{
BlockchainName: blockchainName,
},
privateKey,
common.HexToAddress(sidecar.PoAValidatorManagerOwner),
avaGoBootstrapValidators,
aggregatorExtraPeerEndpoints,
); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("Subnet is successfully converted into Subnet Only Validator")
}
rpcURL, _, err := contract.GetBlockchainEndpoints(
app,
network,
chainSpec,
true,
false,
)
if err != nil {
return err
}
aggregatorExtraPeerEndpoints, err := GetAggregatorExtraPeerEndpoints(network)
if err != nil {
return err
}
if err := validatormanager.SetupPoA(
app,
network,
rpcURL,
contract.ChainSpec{
BlockchainName: blockchainName,
},
privateKey,
common.HexToAddress(sidecar.PoAValidatorManagerOwner),
avaGoBootstrapValidators,
aggregatorExtraPeerEndpoints,
); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("Subnet is successfully converted into Subnet Only Validator")
}

flags := make(map[string]string)
Expand Down
93 changes: 3 additions & 90 deletions cmd/nodecmd/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

import (
"fmt"
"github.com/ava-labs/avalanche-cli/pkg/node"

Check failure on line 7 in cmd/nodecmd/local.go

View workflow job for this annotation

GitHub Actions / Lint

File is not `gofumpt`-ed (gofumpt)
"os"
"path/filepath"

Check failure on line 9 in cmd/nodecmd/local.go

View workflow job for this annotation

GitHub Actions / Lint

File is not `gofumpt`-ed (gofumpt)

"github.com/ava-labs/avalanche-cli/pkg/binutils"
"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
Expand All @@ -17,9 +18,6 @@
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanche-network-runner/client"
anrutils "github.com/ava-labs/avalanche-network-runner/utils"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -388,14 +386,14 @@
func localDestroyNode(_ *cobra.Command, args []string) error {
clusterName := args[0]

localStopNode(nil, nil)

Check failure on line 389 in cmd/nodecmd/local.go

View workflow job for this annotation

GitHub Actions / Lint

Error return value is not checked (errcheck)

rootDir := app.GetLocalDir(clusterName)
if err := os.RemoveAll(rootDir); err != nil {
return err
}

if ok, err := checkClusterIsLocal(clusterName); err != nil || !ok {
if ok, err := node.CheckClusterIsLocal(app, clusterName); err != nil || !ok {
return fmt.Errorf("local cluster %q not found", clusterName)
}

Expand Down Expand Up @@ -425,93 +423,8 @@
return app.WriteClustersConfigFile(&clustersConfig)
}

func checkClusterIsLocal(clusterName string) (bool, error) {
clustersConfig := models.ClustersConfig{}
if app.ClustersConfigExists() {
var err error
clustersConfig, err = app.LoadClustersConfig()
if err != nil {
return false, err
}
}
clusterConf, ok := clustersConfig.Clusters[clusterName]
return ok && clusterConf.Local, nil
}

func localTrack(_ *cobra.Command, args []string) error {
clusterName := args[0]
blockchainName := args[1]
if ok, err := checkClusterIsLocal(clusterName); err != nil || !ok {
return fmt.Errorf("local node %q is not found", clusterName)
}
sc, err := app.LoadSidecar(blockchainName)
if err != nil {
return err
}
clustersConfig, err := app.LoadClustersConfig()
if err != nil {
return err
}
clusterConfig := clustersConfig.Clusters[clusterName]
network := clusterConfig.Network
if sc.Networks[network.Name()].BlockchainID == ids.Empty {
return fmt.Errorf("blockchain %s has not been deployed to %s", blockchainName, network.Name())
}
subnetID := sc.Networks[network.Name()].SubnetID
chainVMID, err := anrutils.VMID(blockchainName)
if err != nil {
return fmt.Errorf("failed to create VM ID from %s: %w", blockchainName, err)
}
var vmBin string
switch sc.VM {
case models.SubnetEvm:
_, vmBin, err = binutils.SetupSubnetEVM(app, sc.VMVersion)
if err != nil {
return fmt.Errorf("failed to install subnet-evm: %w", err)
}
case models.CustomVM:
vmBin = binutils.SetupCustomBin(app, blockchainName)
default:
return fmt.Errorf("unknown vm: %s", sc.VM)
}
binaryDownloader := binutils.NewPluginBinaryDownloader(app)
if err := binaryDownloader.InstallVM(chainVMID.String(), vmBin); err != nil {
return err
}
cli, err := binutils.NewGRPCClientWithEndpoint(
binutils.LocalClusterGRPCServerEndpoint,
binutils.WithAvoidRPCVersionCheck(true),
binutils.WithDialTimeout(constants.FastGRPCDialTimeout),
)
if err != nil {
return err
}
ctx, cancel := utils.GetANRContext()
defer cancel()
status, err := cli.Status(ctx)
if err != nil {
return err
}
publicEndpoints := []string{}
for _, nodeInfo := range status.ClusterInfo.NodeInfos {
if _, err := cli.RestartNode(ctx, nodeInfo.Name, client.WithWhitelistedSubnets(subnetID.String())); err != nil {
return err
}
publicEndpoints = append(publicEndpoints, nodeInfo.Uri)
}
networkInfo := sc.Networks[network.Name()]
rpcEndpoints := set.Of(networkInfo.RPCEndpoints...)
wsEndpoints := set.Of(networkInfo.WSEndpoints...)
for _, publicEndpoint := range publicEndpoints {
rpcEndpoints.Add(getRPCEndpoint(publicEndpoint, networkInfo.BlockchainID.String()))
wsEndpoints.Add(getWSEndpoint(publicEndpoint, networkInfo.BlockchainID.String()))
}
networkInfo.RPCEndpoints = rpcEndpoints.List()
networkInfo.WSEndpoints = wsEndpoints.List()
sc.Networks[clusterConfig.Network.Name()] = networkInfo
if err := app.UpdateSidecar(&sc); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("%s successfully tracking %s", clusterName, blockchainName)
return nil
return node.TrackSubnetWithLocalMachine(app, clusterName, blockchainName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure it is the moment to move this to node pgk. we keep a part of logic here and a part in node.
also, maybe node is not the final dest package.

}
Loading
Loading