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

Convert Subnet in 1 command #2230

Merged
merged 5 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 52 additions & 53 deletions cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"strings"
"time"

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

"github.com/ava-labs/avalanchego/vms/platformvm/warp/message"
"github.com/ethereum/go-ethereum/common"

Expand Down Expand Up @@ -622,7 +624,7 @@
}
deployer.CleanCacheWallet()
managerAddress := common.HexToAddress(validatormanager.ValidatorContractAddress)
isFullySigned, ConvertL1TxID, tx, remainingSubnetAuthKeys, err := deployer.ConvertL1(

Check warning on line 627 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 @@ -684,62 +686,59 @@
return err
}

if false {
chainSpec := contract.ChainSpec{
clusterName, err := node.GetClusterNameFromList(app)
if err != nil {
return err
}

if err = node.SyncSubnet(app, clusterName, blockchainName, true, nil); err != nil {
return err
}

if err := node.WaitForHealthyCluster(app, clusterName, node.HealthCheckTimeout, node.HealthCheckPoolTime); err != nil {
return err
}

chainSpec := contract.ChainSpec{
BlockchainName: blockchainName,
}
_, genesisPrivateKey, err := contract.GetEVMSubnetPrefundedKey(
app,
network,
chainSpec,
)
if err != nil {
return err
}
rpcURL, _, err := contract.GetBlockchainEndpoints(
app,
network,
chainSpec,
true,
false,
)
if err != nil {
return err
}
if err := validatormanager.SetupPoA(
app,
network,
rpcURL,
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
}
}
rpcURL, _, err := contract.GetBlockchainEndpoints(
app,
network,
chainSpec,
true,
false,
)
if err != nil {
return err
}
if err := validatormanager.SetupPoA(
app,
network,
rpcURL,
contract.ChainSpec{
BlockchainName: blockchainName,
},
privateKey,
common.HexToAddress(sidecar.PoAValidatorManagerOwner),
avaGoBootstrapValidators,
); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("Subnet is successfully converted into Subnet Only Validator")
},
genesisPrivateKey,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No longer asking which private key to use to pay because I think we should jsut make the main funded account default

common.HexToAddress(sidecar.PoAValidatorManagerOwner),
avaGoBootstrapValidators,
); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("L1 is successfully converted to sovereign blockchain")
} else {
if err := app.UpdateSidecarNetworks(&sidecar, network, subnetID, blockchainID, "", "", nil); err != nil {
return err
}
}

flags := make(map[string]string)
flags[constants.MetricsNetwork] = network.Name()
metrics.HandleTracking(cmd, constants.MetricsSubnetDeployCommand, app, flags)
Expand Down
55 changes: 2 additions & 53 deletions cmd/nodecmd/wiz.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ func wiz(cmd *cobra.Command, args []string) error {
}
}

if err := waitForHealthyCluster(clusterName, healthCheckTimeout, healthCheckPoolTime); err != nil {
if err := node.WaitForHealthyCluster(app, clusterName, healthCheckTimeout, healthCheckPoolTime); err != nil {
return err
}

Expand Down Expand Up @@ -349,7 +349,7 @@ func wiz(cmd *cobra.Command, args []string) error {
if err := syncSubnet(cmd, []string{clusterName, subnetName}); err != nil {
return err
}
if err := waitForHealthyCluster(clusterName, healthCheckTimeout, healthCheckPoolTime); err != nil {
if err := node.WaitForHealthyCluster(app, clusterName, healthCheckTimeout, healthCheckPoolTime); err != nil {
return err
}
blockchainID := sc.Networks[network.Name()].BlockchainID
Expand Down Expand Up @@ -636,57 +636,6 @@ func checkRPCCompatibility(
return node.CheckHostsAreRPCCompatible(app, hosts, subnetName)
}

func waitForHealthyCluster(
clusterName string,
timeout time.Duration,
poolTime time.Duration,
) error {
ux.Logger.PrintToUser("")
ux.Logger.PrintToUser("Waiting for node(s) in cluster %s to be healthy...", clusterName)
clustersConfig, err := app.LoadClustersConfig()
if err != nil {
return err
}
cluster, ok := clustersConfig.Clusters[clusterName]
if !ok {
return fmt.Errorf("cluster %s does not exist", clusterName)
}
allHosts, err := ansible.GetInventoryFromAnsibleInventoryFile(app.GetAnsibleInventoryDirPath(clusterName))
if err != nil {
return err
}
hosts := cluster.GetValidatorHosts(allHosts) // exlude api nodes
defer node.DisconnectHosts(hosts)
startTime := time.Now()
spinSession := ux.NewUserSpinner()
spinner := spinSession.SpinToUser("Checking if node(s) are healthy...")
for {
unhealthyNodes, err := node.GetUnhealthyNodes(hosts)
if err != nil {
ux.SpinFailWithError(spinner, "", err)
return err
}
if len(unhealthyNodes) == 0 {
ux.SpinComplete(spinner)
spinSession.Stop()
ux.Logger.GreenCheckmarkToUser("Nodes healthy after %d seconds", uint32(time.Since(startTime).Seconds()))
return nil
}
if time.Since(startTime) > timeout {
ux.SpinFailWithError(spinner, "", fmt.Errorf("cluster not healthy after %d seconds", uint32(timeout.Seconds())))
spinSession.Stop()
ux.Logger.PrintToUser("")
ux.Logger.RedXToUser("Unhealthy Nodes")
for _, failedNode := range unhealthyNodes {
ux.Logger.PrintToUser(" " + failedNode)
}
ux.Logger.PrintToUser("")
return fmt.Errorf("cluster not healthy after %d seconds", uint32(timeout.Seconds()))
}
time.Sleep(poolTime)
}
}

func waitForSubnetValidators(
network models.Network,
clusterName string,
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.8
require (
github.com/ava-labs/apm v1.0.0
github.com/ava-labs/avalanche-network-runner v1.8.4-0.20241005224128-cc3c07bb1344
github.com/ava-labs/avalanchego v1.12.0-initial-poc.3
github.com/ava-labs/avalanchego v1.12.0-initial-poc.5
github.com/ava-labs/awm-relayer v1.4.1-0.20241003162124-807fd305670f
github.com/ava-labs/coreth v0.13.8
github.com/ava-labs/subnet-evm v0.6.10
Expand Down Expand Up @@ -115,7 +115,6 @@ require (
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/gliderlabs/ssh v0.3.7 // indirect
github.com/go-cmd/cmd v1.4.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
Expand Down
8 changes: 2 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ github.com/ava-labs/apm v1.0.0 h1:6FwozH67hEkbWVsOXNZGexBy5KLpNeYucN9zcFUHv+Q=
github.com/ava-labs/apm v1.0.0/go.mod h1:TJL7pTlZNvQatsQPsLUtDHApEwVZ/qS7iSNtRFU83mc=
github.com/ava-labs/avalanche-network-runner v1.8.4-0.20241005224128-cc3c07bb1344 h1:wD/rBr+QKztcKtRtBNqPjzMhwcxnVcuJ3GT62DdgS2Q=
github.com/ava-labs/avalanche-network-runner v1.8.4-0.20241005224128-cc3c07bb1344/go.mod h1:l4QzFnujbyyyeq6oBQ4F6sw9TrTQCjD2V4vUd7ZBCCo=
github.com/ava-labs/avalanchego v1.12.0-initial-poc.3 h1:JfVooBCdMzpeGUT9/phJNl2GHflkGehlMJokXeWKa2A=
github.com/ava-labs/avalanchego v1.12.0-initial-poc.3/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE=
github.com/ava-labs/avalanchego v1.12.0-initial-poc.5 h1:gW4xAqZNvkA4gP8M9yDyd7YUzuwfQbbCR+hgd1ztOto=
github.com/ava-labs/avalanchego v1.12.0-initial-poc.5/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE=
github.com/ava-labs/awm-relayer v1.4.1-0.20241003162124-807fd305670f h1:YUQF1wQJeEcTMC5W/OrwgSFTFMS4zeCM8O02rLeEDow=
github.com/ava-labs/awm-relayer v1.4.1-0.20241003162124-807fd305670f/go.mod h1:K01Md6zPkOFRWeQyxmZ/t9HJfoNgUGqa1L8rOp35GXw=
github.com/ava-labs/coreth v0.13.8 h1:f14X3KgwHl9LwzfxlN6S4bbn5VA2rhEsNnHaRLSTo/8=
Expand Down Expand Up @@ -332,8 +332,6 @@ github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-cmd/cmd v1.4.1 h1:JUcEIE84v8DSy02XTZpUDeGKExk2oW3DA10hTjbQwmc=
github.com/go-cmd/cmd v1.4.1/go.mod h1:tbBenttXtZU4c5djS1o7PWL5pd2xAr5sIqH1kGdNiRc=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
Expand Down Expand Up @@ -368,8 +366,6 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
Expand Down
78 changes: 78 additions & 0 deletions pkg/node/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (
"encoding/json"
"fmt"
"sync"
"time"

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

"github.com/ava-labs/avalanche-cli/pkg/application"
"github.com/ava-labs/avalanche-cli/pkg/constants"
Expand All @@ -16,6 +19,11 @@ import (
"github.com/ava-labs/avalanchego/api/info"
)

const (
HealthCheckPoolTime = 60 * time.Second
HealthCheckTimeout = 3 * time.Minute
)

func AuthorizedAccessFromSettings(app *application.Avalanche) bool {
return app.Conf.GetConfigBoolValue(constants.ConfigAuthorizeCloudAccessKey)
}
Expand Down Expand Up @@ -218,3 +226,73 @@ func parseHealthyOutput(byteValue []byte) (bool, error) {
}
return false, fmt.Errorf("unable to parse node healthy status")
}

func WaitForHealthyCluster(
app *application.Avalanche,
clusterName string,
timeout time.Duration,
poolTime time.Duration,
) error {
ux.Logger.PrintToUser("")
ux.Logger.PrintToUser("Waiting for node(s) in cluster %s to be healthy...", clusterName)
clustersConfig, err := app.LoadClustersConfig()
if err != nil {
return err
}
cluster, ok := clustersConfig.Clusters[clusterName]
if !ok {
return fmt.Errorf("cluster %s does not exist", clusterName)
}
allHosts, err := ansible.GetInventoryFromAnsibleInventoryFile(app.GetAnsibleInventoryDirPath(clusterName))
if err != nil {
return err
}
hosts := cluster.GetValidatorHosts(allHosts) // exlude api nodes
defer DisconnectHosts(hosts)
startTime := time.Now()
spinSession := ux.NewUserSpinner()
spinner := spinSession.SpinToUser("Checking if node(s) are healthy...")
for {
unhealthyNodes, err := GetUnhealthyNodes(hosts)
if err != nil {
ux.SpinFailWithError(spinner, "", err)
return err
}
if len(unhealthyNodes) == 0 {
ux.SpinComplete(spinner)
spinSession.Stop()
ux.Logger.GreenCheckmarkToUser("Nodes healthy after %d seconds", uint32(time.Since(startTime).Seconds()))
return nil
}
if time.Since(startTime) > timeout {
ux.SpinFailWithError(spinner, "", fmt.Errorf("cluster not healthy after %d seconds", uint32(timeout.Seconds())))
spinSession.Stop()
ux.Logger.PrintToUser("")
ux.Logger.RedXToUser("Unhealthy Nodes")
for _, failedNode := range unhealthyNodes {
ux.Logger.PrintToUser(" " + failedNode)
}
ux.Logger.PrintToUser("")
return fmt.Errorf("cluster not healthy after %d seconds", uint32(timeout.Seconds()))
}
time.Sleep(poolTime)
}
}

func GetClusterNameFromList(app *application.Avalanche) (string, error) {
clusterNames, err := app.ListClusterNames()
if err != nil {
return "", err
}
if len(clusterNames) == 0 {
return "", fmt.Errorf("no Avalanche nodes found that can track the blockchain, please create Avalanche nodes first through `avalanche node create`")
}
clusterName, err := app.Prompt.CaptureList(
"Which cluster of Avalanche nodes would you like to use to track the blockchain?",
clusterNames,
)
if err != nil {
return "", err
}
return clusterName, nil
}
2 changes: 1 addition & 1 deletion pkg/node/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func SyncSubnet(app *application.Avalanche, clusterName, blockchainName string,
if err := trackSubnet(app, hosts, clusterName, clusterConfig.Network, blockchainName, subnetAliases); err != nil {
return err
}
ux.Logger.PrintToUser("Node(s) successfully started syncing with Blockchain!")
ux.Logger.PrintToUser("Node(s) successfully started syncing with blockchain!")
ux.Logger.PrintToUser(fmt.Sprintf("Check node blockchain syncing status with avalanche node status %s --blockchain %s", clusterName, blockchainName))
return nil
}
Expand Down
Loading