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

Validate convert txs #2641

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
115 changes: 93 additions & 22 deletions cmd/blockchaincmd/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/ava-labs/avalanche-cli/pkg/blockchain"
"github.com/ava-labs/avalanche-cli/pkg/clierrors"
"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
"github.com/ava-labs/avalanche-cli/pkg/constants"
"github.com/ava-labs/avalanche-cli/pkg/contract"
Expand Down Expand Up @@ -41,6 +42,8 @@ import (
"github.com/spf13/cobra"
)

var doStrongInputChecks bool

// avalanche blockchain convert
func newConvertCmd() *cobra.Command {
cmd := &cobra.Command{
Expand Down Expand Up @@ -97,6 +100,7 @@ Sovereign L1s require bootstrap validators. avalanche blockchain convert command
cmd.Flags().StringVar(&createFlags.proxyContractOwner, "proxy-contract-owner", "", "EVM address that controls ProxyAdmin for TransparentProxy of ValidatorManager contract")
cmd.Flags().Uint64Var(&createFlags.rewardBasisPoints, "reward-basis-points", 100, "(PoS only) reward basis points for PoS Reward Calculator")
cmd.Flags().StringVar(&validatorManagerAddress, "validator-manager-address", "", "validator manager address")
cmd.Flags().BoolVar(&doStrongInputChecks, "verify-input", true, "check for input confirmation")
return cmd
}

Expand All @@ -106,7 +110,7 @@ func StartLocalMachine(
blockchainName string,
deployBalance,
availableBalance uint64,
) error {
) (bool, error) {
var err error
if network.Kind == models.Local {
useLocalMachine = true
Expand All @@ -117,15 +121,15 @@ func StartLocalMachine(
clusterName = clusterNameFlagValue
clusterConfig, err := app.GetClusterConfig(clusterName)
if err != nil {
return err
return false, err
}
// check if cluster is local
if clusterConfig.Local {
useLocalMachine = true
if len(bootstrapEndpoints) == 0 {
bootstrapEndpoints, err = getLocalBootstrapEndpoints()
if err != nil {
return fmt.Errorf("error getting local host bootstrap endpoints: %w, "+
return false, fmt.Errorf("error getting local host bootstrap endpoints: %w, "+
"please create your local node again and call blockchain deploy command again", err)
}
}
Expand All @@ -142,7 +146,7 @@ func StartLocalMachine(

useLocalMachine, err = app.Prompt.CaptureYesNo("Do you want to use your local machine as a bootstrap validator?")
if err != nil {
return err
return false, err
}
}
// default number of local machine nodes to be 1
Expand All @@ -153,7 +157,7 @@ func StartLocalMachine(
// if no cluster provided - we create one with fmt.Sprintf("%s-local-node-%s", blockchainName, networkNameComponent) name
if useLocalMachine && clusterNameFlagValue == "" {
if clusterExists, err := node.CheckClusterIsLocal(app, clusterName); err != nil {
return err
return false, err
} else if clusterExists {
ux.Logger.PrintToUser("")
ux.Logger.PrintToUser(
Expand All @@ -165,16 +169,16 @@ func StartLocalMachine(
fmt.Sprintf("Do you want to overwrite the current local L1 deploy for %s?", blockchainName),
)
if err != nil {
return err
return false, err
}
if !yes {
return nil
return true, nil
}
_ = node.DestroyLocalNode(app, clusterName)
}
requiredBalance := deployBalance * uint64(numLocalNodes)
if availableBalance < requiredBalance {
return fmt.Errorf(
return false, fmt.Errorf(
"required balance for %d validators dynamic fee on PChain is %d but the given key has %d",
numLocalNodes,
requiredBalance,
Expand All @@ -196,20 +200,20 @@ func StartLocalMachine(
)
if err != nil {
if err != vm.ErrNoAvagoVersion {
return err
return false, err
}
avagoVersion = constants.LatestPreReleaseVersionTag
}
}
avagoBinaryPath, err := localnet.SetupAvalancheGoBinary(app, avagoVersion, avagoBinaryPath)
if err != nil {
return err
return false, err
}
nodeConfig := map[string]interface{}{}
if app.AvagoNodeConfigExists(blockchainName) {
nodeConfig, err = utils.ReadJSON(app.GetAvagoNodeConfigPath(blockchainName))
if err != nil {
return err
return false, err
}
}
if partialSync {
Expand All @@ -234,18 +238,18 @@ func StartLocalMachine(
networkoptions.NetworkFlags{},
nil,
); err != nil {
return err
return false, err
}
clusterNameFlagValue = clusterName
if len(bootstrapEndpoints) == 0 {
bootstrapEndpoints, err = getLocalBootstrapEndpoints()
if err != nil {
return fmt.Errorf("error getting local host bootstrap endpoints: %w, "+
return false, fmt.Errorf("error getting local host bootstrap endpoints: %w, "+
"please create your local node again and call blockchain deploy command again", err)
}
}
}
return nil
return false, nil
}

func InitializeValidatorManager(
Expand Down Expand Up @@ -418,13 +422,44 @@ func convertSubnetToL1(
controlKeysList,
subnetAuthKeysList []string,
validatorManagerAddressStr string,
) ([]*txs.ConvertSubnetToL1Validator, bool, error) {
doStrongInputsCheck bool,
) ([]*txs.ConvertSubnetToL1Validator, bool, bool, error) {
if subnetID == ids.Empty {
return nil, false, false, clierrors.ErrNoSubnetID
}
if blockchainID == ids.Empty {
return nil, false, false, clierrors.ErrNoBlockchainID
}
if !common.IsHexAddress(validatorManagerAddressStr) {
return nil, false, false, clierrors.ErrInvalidValidatorManagerAddress
}
avaGoBootstrapValidators, err := ConvertToAvalancheGoSubnetValidator(bootstrapValidators)
if err != nil {
return avaGoBootstrapValidators, false, err
return avaGoBootstrapValidators, false, false, err
}
deployer.CleanCacheWallet()
managerAddress := common.HexToAddress(validatorManagerAddressStr)

if doStrongInputsCheck {
ux.Logger.PrintToUser("You are about to create a ConvertSubnetToL1Tx on %s with the following content:", network.Name())
ux.Logger.PrintToUser(" Subnet ID: %s", subnetID)
ux.Logger.PrintToUser(" Blockchain ID: %s", blockchainID)
ux.Logger.PrintToUser(" Manager Address: %s", managerAddress.Hex())
ux.Logger.PrintToUser(" Validators:")
for _, val := range bootstrapValidators {
ux.Logger.PrintToUser(" Node ID: %s", val.NodeID)
ux.Logger.PrintToUser(" Balance: %.5f", float64(val.Balance)/float64(units.Avax))
}
ux.Logger.PrintToUser("")
ux.Logger.PrintToUser("Please review the details of the ConvertSubnetToL1 Transaction")
ux.Logger.PrintToUser("")
if doContinue, err := app.Prompt.CaptureYesNo("Do you want to create the transaction?"); err != nil {
return avaGoBootstrapValidators, false, false, err
} else if !doContinue {
return avaGoBootstrapValidators, true, false, err
}
}

isFullySigned, convertL1TxID, tx, remainingSubnetAuthKeys, err := deployer.ConvertL1(
controlKeysList,
subnetAuthKeysList,
Expand All @@ -435,7 +470,7 @@ func convertSubnetToL1(
)
if err != nil {
ux.Logger.RedXToUser("error converting blockchain: %s. fix the issue and try again with a new convert cmd", err)
return avaGoBootstrapValidators, false, err
return avaGoBootstrapValidators, false, false, err
}

savePartialTx := !isFullySigned && err == nil
Expand All @@ -450,7 +485,7 @@ func convertSubnetToL1(
outputTxPath,
false,
); err != nil {
return avaGoBootstrapValidators, savePartialTx, err
return avaGoBootstrapValidators, false, savePartialTx, err
}
} else {
ux.Logger.PrintToUser("ConvertSubnetToL1Tx ID: %s", convertL1TxID)
Expand All @@ -460,13 +495,13 @@ func convertSubnetToL1(
0,
)
if err != nil {
return avaGoBootstrapValidators, savePartialTx, err
return avaGoBootstrapValidators, false, savePartialTx, err
}
}

ux.Logger.PrintToUser("")
setBootstrapValidatorValidationID(avaGoBootstrapValidators, bootstrapValidators, subnetID)
return avaGoBootstrapValidators, savePartialTx, app.UpdateSidecarNetworks(
return avaGoBootstrapValidators, false, savePartialTx, app.UpdateSidecarNetworks(
&sidecar,
network,
subnetID,
Expand Down Expand Up @@ -526,6 +561,36 @@ func convertBlockchain(_ *cobra.Command, args []string) error {
subnetID := sidecar.Networks[network.Name()].SubnetID
blockchainID := sidecar.Networks[network.Name()].BlockchainID

if doStrongInputChecks && subnetID != ids.Empty {
ux.Logger.PrintToUser("Subnet ID to be used is %s", subnetID)
if acceptValue, err := app.Prompt.CaptureYesNo("Is this value correct?"); err != nil {
return err
} else if !acceptValue {
subnetID = ids.Empty
}
}
Comment on lines +564 to +571
Copy link
Collaborator

Choose a reason for hiding this comment

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

i dont think we need to do this check because users will already check details of subnet id and blockchain id in line 444. A user not using skip check flag will have to verify three times

Copy link
Collaborator Author

@felipemadero felipemadero Feb 26, 2025

Choose a reason for hiding this comment

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

A user will have to verify two times, not three times (unless I miss something). And
the second verification includes much more information.
This specific check and input for blockchain id was requested and accorded (i added the subnet id
which is in similar state), so probably the 444 check can be
removed. I will let devrel to vote on this cc @martineckardt after trying out the command.
cc @learyce

if subnetID == ids.Empty {
subnetID, err = app.Prompt.CaptureID("What is the subnet ID?")
if err != nil {
return err
}
}

if doStrongInputChecks && blockchainID != ids.Empty {
ux.Logger.PrintToUser("Blockchain ID to be used is %s", blockchainID)
if acceptValue, err := app.Prompt.CaptureYesNo("Is this value correct?"); err != nil {
return err
} else if !acceptValue {
blockchainID = ids.Empty
}
}
Comment on lines +579 to +586
Copy link
Collaborator

Choose a reason for hiding this comment

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

same comment as above

if blockchainID == ids.Empty {
blockchainID, err = app.Prompt.CaptureID("What is the blockchain ID?")
if err != nil {
return err
}
}

if validatorManagerAddress == "" {
validatorManagerAddressAddrFmt, err := app.Prompt.CaptureAddress("What is the address of the Validator Manager?")
if err != nil {
Expand Down Expand Up @@ -577,8 +642,10 @@ func convertBlockchain(_ *cobra.Command, args []string) error {
}
}
if !generateNodeID {
if err = StartLocalMachine(network, sidecar, blockchainName, deployBalance, availableBalance); err != nil {
if cancel, err := StartLocalMachine(network, sidecar, blockchainName, deployBalance, availableBalance); err != nil {
return err
} else if cancel {
return nil
}
}
switch {
Expand Down Expand Up @@ -666,7 +733,7 @@ func convertBlockchain(_ *cobra.Command, args []string) error {
// deploy to public network
deployer := subnet.NewPublicDeployer(app, kc, network)

avaGoBootstrapValidators, savePartialTx, err := convertSubnetToL1(
avaGoBootstrapValidators, cancel, savePartialTx, err := convertSubnetToL1(
bootstrapValidators,
deployer,
subnetID,
Expand All @@ -677,10 +744,14 @@ func convertBlockchain(_ *cobra.Command, args []string) error {
controlKeys,
subnetAuthKeys,
validatorManagerAddress,
doStrongInputChecks,
)
if err != nil {
return err
}
if cancel {
return nil
}

if savePartialTx {
return nil
Expand Down
10 changes: 8 additions & 2 deletions cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,10 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
}
}
if !generateNodeID {
if err = StartLocalMachine(network, sidecar, blockchainName, deployBalance, availableBalance); err != nil {
if cancel, err := StartLocalMachine(network, sidecar, blockchainName, deployBalance, availableBalance); err != nil {
return err
} else if cancel {
return nil
}
}
switch {
Expand Down Expand Up @@ -773,7 +775,7 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {

if sidecar.Sovereign {
validatorManagerStr := validatorManagerSDK.ProxyContractAddress
avaGoBootstrapValidators, savePartialTx, err := convertSubnetToL1(
avaGoBootstrapValidators, cancel, savePartialTx, err := convertSubnetToL1(
bootstrapValidators,
deployer,
subnetID,
Expand All @@ -784,10 +786,14 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
controlKeys,
subnetAuthKeys,
validatorManagerStr,
false,
)
if err != nil {
return err
}
if cancel {
return nil
}

if savePartialTx {
return nil
Expand Down
3 changes: 2 additions & 1 deletion cmd/blockchaincmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/ava-labs/avalanche-cli/pkg/application"
"github.com/ava-labs/avalanche-cli/pkg/binutils"
"github.com/ava-labs/avalanche-cli/pkg/clierrors"
"github.com/ava-labs/avalanche-cli/pkg/contract"
"github.com/ava-labs/avalanche-cli/pkg/keychain"
"github.com/ava-labs/avalanche-cli/pkg/models"
Expand Down Expand Up @@ -85,7 +86,7 @@ func UpdateKeychainWithSubnetControlKeys(
}
subnetID := sc.Networks[network.Name()].SubnetID
if subnetID == ids.Empty {
return errNoSubnetID
return clierrors.ErrNoSubnetID
}
_, controlKeys, _, err := txutils.GetOwners(network, subnetID)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion cmd/blockchaincmd/remove_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/ava-labs/avalanche-cli/pkg/blockchain"
"github.com/ava-labs/avalanche-cli/pkg/clierrors"
"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
"github.com/ava-labs/avalanche-cli/pkg/constants"
"github.com/ava-labs/avalanche-cli/pkg/contract"
Expand Down Expand Up @@ -117,7 +118,7 @@ func removeValidator(_ *cobra.Command, args []string) error {
scNetwork := sc.Networks[network.Name()]
subnetID := scNetwork.SubnetID
if subnetID == ids.Empty {
return errNoSubnetID
return clierrors.ErrNoSubnetID
}

var nodeID ids.NodeID
Expand Down
7 changes: 4 additions & 3 deletions cmd/nodecmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ import (
"strings"
"sync"

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

"github.com/ava-labs/avalanche-cli/cmd/blockchaincmd"
"github.com/ava-labs/avalanche-cli/pkg/ansible"
"github.com/ava-labs/avalanche-cli/pkg/clierrors"
"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
"github.com/ava-labs/avalanche-cli/pkg/models"
"github.com/ava-labs/avalanche-cli/pkg/node"
"github.com/ava-labs/avalanche-cli/pkg/ssh"
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/vms/platformvm/status"

"github.com/olekukonko/tablewriter"
"github.com/pborman/ansi"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -71,7 +72,7 @@ func statusNode(_ *cobra.Command, args []string) error {
}
blockchainID = sc.Networks[clusterConf.Network.Name()].BlockchainID
if blockchainID == ids.Empty {
return ErrNoBlockchainID
return clierrors.ErrNoBlockchainID
}
}

Expand Down
2 changes: 0 additions & 2 deletions cmd/nodecmd/validate_primary.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ var (
useCustomDuration bool
ErrMutuallyExlusiveKeyLedger = errors.New("--key and --ledger,--ledger-addrs are mutually exclusive")
ErrStoredKeyOnMainnet = errors.New("--key is not available for mainnet operations")
ErrNoBlockchainID = errors.New("failed to find the blockchain ID for this subnet, has it been deployed/created on this network?")
ErrNoSubnetID = errors.New("failed to find the subnet ID for this subnet, has it been deployed/created on this network?")
)

func newValidatePrimaryCmd() *cobra.Command {
Expand Down
Loading
Loading