diff --git a/cmd/blockchaincmd/add_validator.go b/cmd/blockchaincmd/add_validator.go index 12cfbff40..d6d92107f 100644 --- a/cmd/blockchaincmd/add_validator.go +++ b/cmd/blockchaincmd/add_validator.go @@ -59,7 +59,7 @@ var ( // avalanche blockchain addValidator func newAddValidatorCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "addValidator [blockchainName] [nodeID]", + Use: "addValidator [blockchainName]", Short: "Allow a validator to validate your blockchain's subnet", Long: `The blockchain addValidator command whitelists a primary network validator to validate the subnet of the provided deployed Blockchain. @@ -72,7 +72,7 @@ these prompts by providing the values with flags. This command currently only works on Blockchains deployed to either the Fuji Testnet or Mainnet.`, RunE: addValidator, - Args: cobrautils.ExactArgs(2), + Args: cobrautils.ExactArgs(1), } networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, addValidatorSupportedNetworkOptions) @@ -82,20 +82,20 @@ Testnet or Mainnet.`, cmd.Flags().BoolVarP(&useEwoq, "ewoq", "e", false, "use ewoq key [fuji/devnet only]") cmd.Flags().BoolVarP(&useLedger, "ledger", "g", false, "use ledger instead of key (always true on mainnet, defaults to false on fuji/devnet)") cmd.Flags().StringSliceVar(&ledgerAddresses, "ledger-addrs", []string{}, "use the given ledger addresses") - cmd.Flags().BoolVar(&nonSOV, "not-sov", false, "set to true if adding validator to a non-SOV blockchain") - cmd.Flags().StringVar(&publicKey, "public-key", "", "set the BLS public key of the validator to add") - cmd.Flags().StringVar(&pop, "proof-of-possession", "", "set the BLS proof of possession of the validator to add") + cmd.Flags().BoolVar(&sovereign, "sovereign", true, "set to false if adding validator to a non-sovereign blockchain") + cmd.Flags().StringVar(&nodeIDStr, "node-id", "", "node-id of the validator to add") + cmd.Flags().StringVar(&publicKey, "bls-public-key", "", "set the BLS public key of the validator to add") + cmd.Flags().StringVar(&pop, "bls-proof-of-possession", "", "set the BLS proof of possession of the validator to add") cmd.Flags().StringVar(&changeAddr, "change-address", "", "P-Chain address that will receive any leftover AVAX from the validator when it is removed from Subnet") return cmd } func addValidator(_ *cobra.Command, args []string) error { blockchainName := args[0] - _, err := ids.NodeIDFromString(args[1]) + err := prompts.ValidateNodeID(nodeIDStr) if err != nil { return err } - nodeIDStr = args[1] network, err := networkoptions.GetNetworkFromCmdLineFlags( app, @@ -124,13 +124,13 @@ func addValidator(_ *cobra.Command, args []string) error { return err } network.HandlePublicNetworkSimulation() - if nonSOV { + if !sovereign { if err := UpdateKeychainWithSubnetControlKeys(kc, network, blockchainName); err != nil { return err } } deployer := subnet.NewPublicDeployer(app, kc, network) - if nonSOV { + if !sovereign { return CallAddValidatorNonSOV(deployer, network, kc, useLedger, blockchainName, nodeIDStr, defaultValidatorParams, waitForTxAcceptance) } return CallAddValidator(deployer, network, kc, useLedger, blockchainName, nodeIDStr) @@ -197,6 +197,14 @@ func CallAddValidator( // return err //} + if nodeIDStr == "" { + nodeID, err := PromptNodeID("add as a blockchain validator") + if err != nil { + return err + } + nodeIDStr = nodeID.String() + } + publicKey, pop, err = promptProofOfPossession(publicKey == "", pop == "") if err != nil { return err @@ -223,28 +231,6 @@ func CallAddValidator( ux.Logger.PrintToUser("Change Address: %s", changeAddr) ux.Logger.PrintToUser("Inputs complete, issuing transaction to add the provided validator information...") - //type RegisterSubnetValidatorTx struct { - // // Metadata, inputs and outputs - // BaseTx - // // Balance <= sum($AVAX inputs) - sum($AVAX outputs) - TxFee. - // Balance uint64 `json:"balance"` - // // [Signer] is the BLS key for this validator. - // // Note: We do not enforce that the BLS key is unique across all validators. - // // This means that validators can share a key if they so choose. - // // However, a NodeID does uniquely map to a BLS key - // Signer signer.Signer `json:"signer"` - // // Leftover $AVAX from the Subnet Validator's Balance will be issued to - // // this owner after it is removed from the validator set. - // ChangeOwner fx.Owner `json:"changeOwner"` - // // AddressedCall with Payload: - // // - SubnetID - // // - NodeID (must be Ed25519 NodeID) - // // - Weight - // // - BLS public key - // // - Expiry - // Message warp.Message `json:"message"` - //} - blsInfo, err := getBLSInfo(publicKey, pop) if err != nil { return fmt.Errorf("failure parsing BLS info: %w", err) @@ -275,7 +261,7 @@ func CallAddValidator( return nil } -func generateWarpMessageAddValidator(SubnetID ids.ID, NodeID ids.NodeID, weight uint64, blsPublicKey string, expiry uint64) (warpPlatformVM.Message, error) { +func generateWarpMessageAddValidator(subnetID ids.ID, nodeID ids.NodeID, weight uint64, blsPublicKey string, expiry uint64) (warpPlatformVM.Message, error) { return warpPlatformVM.Message{}, nil } diff --git a/cmd/blockchaincmd/blockchain.go b/cmd/blockchaincmd/blockchain.go index 8d937ee27..54989cd6c 100644 --- a/cmd/blockchaincmd/blockchain.go +++ b/cmd/blockchaincmd/blockchain.go @@ -61,6 +61,6 @@ manage your Blockchain configurations and live deployments.`, // subnet changeOwner cmd.AddCommand(newChangeOwnerCmd()) // subnet changeWeight - cmd.AddCommand(newSetWeightCmd()) + cmd.AddCommand(newChangeWeightCmd()) return cmd } diff --git a/cmd/blockchaincmd/change_weight.go b/cmd/blockchaincmd/change_weight.go index 46049160d..af1760ba6 100644 --- a/cmd/blockchaincmd/change_weight.go +++ b/cmd/blockchaincmd/change_weight.go @@ -5,6 +5,8 @@ package blockchaincmd import ( "errors" "fmt" + "os" + "github.com/ava-labs/avalanche-cli/pkg/cobrautils" "github.com/ava-labs/avalanche-cli/pkg/constants" "github.com/ava-labs/avalanche-cli/pkg/keychain" @@ -15,27 +17,25 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/ux" "github.com/ava-labs/avalanchego/ids" "github.com/spf13/cobra" - "os" ) -var () - -// avalanche blockchain setWeight -func newSetWeightCmd() *cobra.Command { +// avalanche blockchain addValidator +func newChangeWeightCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "setWeight [blockchainName] [nodeID]", - Short: "Updates the weight of a Subnet validator", - Long: `The blockchain changeWeight command updates the weight of a Subnet Validator. + Use: "changeWeight [blockchainName]", + Short: "Changes the weight of a Subnet validator", + Long: `The blockchain changeWeight command changes the weight of a Subnet Validator. The Subnet has to be a Proof of Authority Subnet-Only Validator Subnet.`, RunE: setWeight, - Args: cobrautils.ExactArgs(2), + Args: cobrautils.ExactArgs(1), } networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, addValidatorSupportedNetworkOptions) cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji/devnet only]") cmd.Flags().Uint64Var(&weight, "weight", constants.BootstrapValidatorWeight, "set the new staking weight of the validator") cmd.Flags().BoolVarP(&useEwoq, "ewoq", "e", false, "use ewoq key [fuji/devnet only]") + cmd.Flags().StringVar(&nodeIDStr, "node-id", "", "node-id of the validator") cmd.Flags().BoolVarP(&useLedger, "ledger", "g", false, "use ledger instead of key (always true on mainnet, defaults to false on fuji/devnet)") cmd.Flags().StringSliceVar(&ledgerAddresses, "ledger-addrs", []string{}, "use the given ledger addresses") return cmd @@ -43,14 +43,10 @@ The Subnet has to be a Proof of Authority Subnet-Only Validator Subnet.`, func setWeight(_ *cobra.Command, args []string) error { blockchainName := args[0] - _, err := ids.NodeIDFromString(args[1]) + err := prompts.ValidateNodeID(nodeIDStr) if err != nil { return err } - nodeIDStr = args[1] - - //TODO: add check for non SOV subnet - // return err if non SOV network, err := networkoptions.GetNetworkFromCmdLineFlags( app, @@ -122,9 +118,17 @@ func setWeight(_ *cobra.Command, args []string) error { return errNoSubnetID } - nodeID, err := ids.NodeIDFromString(nodeIDStr) - if err != nil { - return err + var nodeID ids.NodeID + if nodeIDStr == "" { + nodeID, err = PromptNodeID("add as a blockchain validator") + if err != nil { + return err + } + } else { + nodeID, err = ids.NodeIDFromString(nodeIDStr) + if err != nil { + return err + } } isValidator, err := subnet.IsSubnetValidator(subnetID, nodeID, network) @@ -147,7 +151,7 @@ func setWeight(_ *cobra.Command, args []string) error { // TODO: we need to wait for the balance from the removed validator to arrive in changeAddr // set arbitrary time.sleep here? - weight, err = promptWeightSubnetValidator() + weight, err = app.Prompt.CaptureWeight("What weight would you like to assign to the validator?") if err != nil { return err } @@ -168,17 +172,7 @@ func setWeight(_ *cobra.Command, args []string) error { } // add back validator to subnet with updated weight - return CallAddValidator(deployer, network, kc, useLedger, blockchainName, nodeIDStr) -} - -// TODO: implement checkIfSubnetIsSOV -// checkIfSubnetIsSOV returns true if Subnet is SOV from P Chain -func checkIfSubnetIsSOV() (bool, error) { - return false, nil -} -func promptWeightSubnetValidator() (uint64, error) { - txt := "What weight would you like to assign to the validator?" - return app.Prompt.CaptureWeight(txt) + return CallAddValidator(deployer, network, kc, useLedger, blockchainName, nodeID.String()) } // getValidatorBalanceFromPChain gets remaining balance of validator from p chain diff --git a/cmd/blockchaincmd/convert.go b/cmd/blockchaincmd/convert.go deleted file mode 100644 index 979a5a5a8..000000000 --- a/cmd/blockchaincmd/convert.go +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright (C) 2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. -package blockchaincmd - -import ( - "github.com/ava-labs/avalanche-cli/pkg/cobrautils" - "github.com/ava-labs/avalanche-cli/pkg/networkoptions" - "github.com/spf13/cobra" -) - -// avalanche l1 convert -func newConvertCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "convert [l1Name]", - Short: "Converts an Avalanche L1 into a SOV (Subnet Only Validator) L1", - Long: `The l1 convert command converts a non-SOV Avalanche L1 (which requires subnet -validators to have at least 2000 AVAX staked in the Primary Network) into an SOV (Subnet Only -Validator) L1. - -Once an L1 is successfully converted into a an SOV, the Owner Keys can no longer be used to modify -the L1's validator set. In addition, AddSubnetValidatorTx is disabled on the Subnet going forward. -The only action that the Owner key is able to take is removing any L1 validators that were added -using AddSubnetValidatorTx previously via RemoveSubnetValidatorTx. - -Unless removed by the Owner key, any Subnet Validators added previously with an AddSubnetValidatorTx -will continue to validate the Subnet until their End time is reached. Once all Subnet Validators -added with AddSubnetValidatorTx are no longer in the validator set, the Owner key is powerless. -RegisterL1ValidatorTx and SetL1ValidatorWeightTx must be used to manage the Subnet's -validator set going forward.`, - RunE: convertL1, - PersistentPostRun: handlePostRun, - Args: cobrautils.ExactArgs(1), - } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, deploySupportedNetworkOptions) - cmd.Flags().StringVar(&userProvidedAvagoVersion, "avalanchego-version", "latest", "use this version of avalanchego (ex: v1.17.12)") - cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji/devnet deploy only]") - cmd.Flags().BoolVarP(&sameControlKey, "same-control-key", "s", false, "use the fee-paying key as control key") - cmd.Flags().Uint32Var(&threshold, "threshold", 0, "required number of control key signatures to make subnet changes") - cmd.Flags().StringSliceVar(&controlKeys, "control-keys", nil, "addresses that may make subnet changes") - cmd.Flags().StringSliceVar(&subnetAuthKeys, "subnet-auth-keys", nil, "control keys that will be used to authenticate chain creation") - cmd.Flags().StringVar(&outputTxPath, "output-tx-path", "", "file path of the blockchain creation tx") - cmd.Flags().BoolVarP(&useEwoq, "ewoq", "e", false, "use ewoq key [fuji/devnet deploy only]") - cmd.Flags().BoolVarP(&useLedger, "ledger", "g", false, "use ledger instead of key (always true on mainnet, defaults to false on fuji/devnet)") - cmd.Flags().StringSliceVar(&ledgerAddresses, "ledger-addrs", []string{}, "use the given ledger addresses") - cmd.Flags().StringVarP(&subnetIDStr, "subnet-id", "u", "", "do not create a subnet, deploy the blockchain into the given subnet id") - cmd.Flags().Uint32Var(&mainnetChainID, "mainnet-chain-id", 0, "use different ChainID for mainnet deployment") - cmd.Flags().StringVar(&avagoBinaryPath, "avalanchego-path", "", "use this avalanchego binary path") - cmd.Flags().BoolVar(&subnetOnly, "subnet-only", false, "only create a subnet") - cmd.Flags().BoolVar(&icmSpec.SkipICMDeploy, "skip-local-teleporter", false, "skip automatic teleporter deploy on local networks [to be deprecated]") - cmd.Flags().BoolVar(&icmSpec.SkipICMDeploy, "skip-teleporter-deploy", false, "skip automatic teleporter deploy") - cmd.Flags().BoolVar(&icmSpec.SkipRelayerDeploy, "skip-relayer", false, "skip relayer deploy") - cmd.Flags().StringVar(&icmSpec.ICMVersion, "teleporter-version", "latest", "teleporter version to deploy") - cmd.Flags().StringVar(&icmSpec.RelayerVersion, "relayer-version", "latest", "relayer version to deploy") - cmd.Flags().StringVar(&icmSpec.MessengerContractAddressPath, "teleporter-messenger-contract-address-path", "", "path to an interchain messenger contract address file") - cmd.Flags().StringVar(&icmSpec.MessengerDeployerAddressPath, "teleporter-messenger-deployer-address-path", "", "path to an interchain messenger deployer address file") - cmd.Flags().StringVar(&icmSpec.MessengerDeployerTxPath, "teleporter-messenger-deployer-tx-path", "", "path to an interchain messenger deployer tx file") - cmd.Flags().StringVar(&icmSpec.RegistryBydecodePath, "teleporter-registry-bytecode-path", "", "path to an interchain messenger registry bytecode file") - cmd.Flags().StringVar(&bootstrapValidatorsJSONFilePath, "bootstrap-filepath", "", "JSON file path that provides details about bootstrap validators, leave Node-ID and BLS values empty if using --generate-node-id=true") - cmd.Flags().BoolVar(&generateNodeID, "generate-node-id", false, "whether to create new node id for bootstrap validators (Node-ID and BLS values in bootstrap JSON file will be overridden if --bootstrap-filepath flag is used)") - return cmd -} - -// // convertL1 is the cobra command run for deploying subnets -func convertL1(cmd *cobra.Command, args []string) error { - //blockchainName := args[0] - // - //if err := CreateBlockchainFirst(cmd, blockchainName, skipCreatePrompt); err != nil { - // return err - //} - // - //chains, err := ValidateSubnetNameAndGetChains(args) - //if err != nil { - // return err - //} - // - //if icmSpec.MessengerContractAddressPath != "" || icmSpec.MessengerDeployerAddressPath != "" || icmSpec.MessengerDeployerTxPath != "" || icmSpec.RegistryBydecodePath != "" { - // if icmSpec.MessengerContractAddressPath == "" || icmSpec.MessengerDeployerAddressPath == "" || icmSpec.MessengerDeployerTxPath == "" || icmSpec.RegistryBydecodePath == "" { - // return fmt.Errorf("if setting any teleporter asset path, you must set all teleporter asset paths") - // } - //} - // - //var bootstrapValidators []models.SubnetValidator - //if bootstrapValidatorsJSONFilePath != "" { - // bootstrapValidators, err = LoadBootstrapValidator(bootstrapValidatorsJSONFilePath) - // if err != nil { - // return err - // } - //} - // - //chain := chains[0] - // - //sidecar, err := app.LoadSidecar(chain) - //if err != nil { - // return fmt.Errorf("failed to load sidecar for later update: %w", err) - //} - // - //if sidecar.ImportedFromAPM { - // return errors.New("unable to deploy subnets imported from a repo") - //} - // - //if outputTxPath != "" { - // if _, err := os.Stat(outputTxPath); err == nil { - // return fmt.Errorf("outputTxPath %q already exists", outputTxPath) - // } - //} - // - //network, err := networkoptions.GetNetworkFromCmdLineFlags( - // app, - // "", - // globalNetworkFlags, - // true, - // false, - // deploySupportedNetworkOptions, - // "", - //) - //if err != nil { - // return err - //} - // - //isEVMGenesis, validationErr, err := app.HasSubnetEVMGenesis(chain) - //if err != nil { - // return err - //} - //if sidecar.VM == models.SubnetEvm && !isEVMGenesis { - // return fmt.Errorf("failed to validate SubnetEVM genesis format: %w", validationErr) - //} - // - //chainGenesis, err := app.LoadRawGenesis(chain) - //if err != nil { - // return err - //} - // - //if isEVMGenesis { - // // is is a subnet evm or a custom vm based on subnet evm - // if network.Kind == models.Mainnet { - // err = getSubnetEVMMainnetChainID(&sidecar, chain) - // if err != nil { - // return err - // } - // chainGenesis, err = updateSubnetEVMGenesisChainID(chainGenesis, sidecar.SubnetEVMMainnetChainID) - // if err != nil { - // return err - // } - // } - // err = checkSubnetEVMDefaultAddressNotInAlloc(network, chain) - // if err != nil { - // return err - // } - //} - // - //if bootstrapValidatorsJSONFilePath == "" { - // bootstrapValidators, err = promptBootstrapValidators(network) - // if err != nil { - // return err - // } - //} - // - //ux.Logger.PrintToUser("Deploying %s to %s", chains, network.Name()) - // - //if network.Kind == models.Local { - // app.Log.Debug("Deploy local") - // - // genesisPath := app.GetGenesisPath(chain) - // - // // copy vm binary to the expected location, first downloading it if necessary - // var vmBin string - // switch sidecar.VM { - // case models.SubnetEvm: - // _, vmBin, err = binutils.SetupSubnetEVM(app, sidecar.VMVersion) - // if err != nil { - // return fmt.Errorf("failed to install subnet-evm: %w", err) - // } - // case models.CustomVM: - // vmBin = binutils.SetupCustomBin(app, chain) - // default: - // return fmt.Errorf("unknown vm: %s", sidecar.VM) - // } - // - // // check if selected version matches what is currently running - // nc := localnet.NewStatusChecker() - // avagoVersion, err := CheckForInvalidDeployAndGetAvagoVersion(nc, sidecar.RPCVersion) - // if err != nil { - // return err - // } - // if avagoBinaryPath == "" { - // userProvidedAvagoVersion = avagoVersion - // } - // - // deployer := subnet.NewLocalDeployer(app, userProvidedAvagoVersion, avagoBinaryPath, vmBin) - // deployInfo, err := deployer.DeployToLocalNetwork(chain, genesisPath, icmSpec, subnetIDStr) - // if err != nil { - // if deployer.BackendStartedHere() { - // if innerErr := binutils.KillgRPCServerProcess(app); innerErr != nil { - // app.Log.Warn("tried to kill the gRPC server process but it failed", zap.Error(innerErr)) - // } - // } - // return err - // } - // flags := make(map[string]string) - // flags[constants.MetricsNetwork] = network.Name() - // metrics.HandleTracking(cmd, constants.MetricsSubnetDeployCommand, app, flags) - // if err := app.UpdateSidecarNetworks( - // &sidecar, - // network, - // deployInfo.SubnetID, - // deployInfo.BlockchainID, - // deployInfo.ICMMessengerAddress, - // deployInfo.ICMRegistryAddress, - // bootstrapValidators, - // ); err != nil { - // return err - // } - // return PrintSubnetInfo(blockchainName, true) - //} - // - //// from here on we are assuming a public deploy - //if subnetOnly && subnetIDStr != "" { - // return errMutuallyExlusiveSubnetFlags - //} - // - //createSubnet := true - //var subnetID ids.ID - //if subnetIDStr != "" { - // subnetID, err = ids.FromString(subnetIDStr) - // if err != nil { - // return err - // } - // createSubnet = false - //} else if !subnetOnly && sidecar.Networks != nil { - // model, ok := sidecar.Networks[network.Name()] - // if ok { - // if model.SubnetID != ids.Empty && model.BlockchainID == ids.Empty { - // subnetID = model.SubnetID - // createSubnet = false - // } - // } - //} - // - //fee := uint64(0) - //if !subnetOnly { - // fee += network.GenesisParams().TxFeeConfig.StaticFeeConfig.CreateBlockchainTxFee - //} - //if createSubnet { - // fee += network.GenesisParams().TxFeeConfig.StaticFeeConfig.CreateSubnetTxFee - //} - // - //kc, err := keychain.GetKeychainFromCmdLineFlags( - // app, - // constants.PayTxsFeesMsg, - // network, - // keyName, - // useEwoq, - // useLedger, - // ledgerAddresses, - // fee, - //) - //if err != nil { - // return err - //} - // - //network.HandlePublicNetworkSimulation() - // - //if createSubnet { - // controlKeys, threshold, err = promptOwners( - // kc, - // controlKeys, - // sameControlKey, - // threshold, - // subnetAuthKeys, - // true, - // ) - // if err != nil { - // return err - // } - //} else { - // ux.Logger.PrintToUser(logging.Blue.Wrap( - // fmt.Sprintf("Deploying into pre-existent subnet ID %s", subnetID.String()), - // )) - // var isPermissioned bool - // isPermissioned, controlKeys, threshold, err = txutils.GetOwners(network, subnetID) - // if err != nil { - // return err - // } - // if !isPermissioned { - // return ErrNotPermissionedSubnet - // } - //} - // - //// add control keys to the keychain whenever possible - //if err := kc.AddAddresses(controlKeys); err != nil { - // return err - //} - // - //kcKeys, err := kc.PChainFormattedStrAddresses() - //if err != nil { - // return err - //} - // - //// get keys for blockchain tx signing - //if subnetAuthKeys != nil { - // if err := prompts.CheckSubnetAuthKeys(kcKeys, subnetAuthKeys, controlKeys, threshold); err != nil { - // return err - // } - //} else { - // subnetAuthKeys, err = prompts.GetSubnetAuthKeys(app.Prompt, kcKeys, controlKeys, threshold) - // if err != nil { - // return err - // } - //} - //ux.Logger.PrintToUser("Your subnet auth keys for chain creation: %s", subnetAuthKeys) - // - //// deploy to public network - //deployer := subnet.NewPublicDeployer(app, kc, network) - // - //if createSubnet { - // subnetID, err = deployer.DeploySubnet(controlKeys, threshold) - // if err != nil { - // return err - // } - // // get the control keys in the same order as the tx - // _, controlKeys, threshold, err = txutils.GetOwners(network, subnetID) - // if err != nil { - // return err - // } - //} - // - //var ( - // savePartialTx bool - // blockchainID ids.ID - // tx *txs.Tx - // remainingSubnetAuthKeys []string - // isFullySigned bool - //) - // - //if !subnetOnly { - // isFullySigned, blockchainID, tx, remainingSubnetAuthKeys, err = deployer.DeployBlockchain( - // controlKeys, - // subnetAuthKeys, - // subnetID, - // chain, - // chainGenesis, - // ) - // if err != nil { - // ux.Logger.PrintToUser(logging.Red.Wrap( - // fmt.Sprintf("error deploying blockchain: %s. fix the issue and try again with a new deploy cmd", err), - // )) - // } - // - // savePartialTx = !isFullySigned && err == nil - //} - // - //if err := PrintDeployResults(chain, subnetID, blockchainID); err != nil { - // return err - //} - // - //if savePartialTx { - // if err := SaveNotFullySignedTx( - // "Blockchain Creation", - // tx, - // chain, - // subnetAuthKeys, - // remainingSubnetAuthKeys, - // outputTxPath, - // false, - // ); err != nil { - // return err - // } - //} - // - //// type ConvertSubnetTx struct { - //// // Metadata, inputs and outputs - //// BaseTx - //// // ID of the Subnet to transform - //// // Restrictions: - //// // - Must not be the Primary Network ID - //// Subnet ids.ID `json:"subnetID"` - //// // BlockchainID where the Subnet manager lives - //// ChainID ids.ID `json:"chainID"` - //// // Address of the Subnet manager - //// Address []byte `json:"address"` - //// // Initial pay-as-you-go validators for the Subnet - //// Validators []SubnetValidator `json:"validators"` - //// // Authorizes this conversion - //// SubnetAuth verify.Verifiable `json:"subnetAuthorization"` - //// } - // - ////avaGoBootstrapValidators, err := convertToAvalancheGoSubnetValidator(bootstrapValidators) - ////if err != nil { - //// return err - ////} - //// TODO: replace with avalanchego subnetValidators once implemented - //isFullySigned, convertSubnetTxID, tx, remainingSubnetAuthKeys, err := deployer.ConvertL1( - // controlKeys, - // subnetAuthKeys, - // subnetID, - // blockchainID, - // // avaGoBootstrapValidators, - //) - //if err != nil { - // ux.Logger.PrintToUser(logging.Red.Wrap( - // fmt.Sprintf("error converting blockchain: %s. fix the issue and try again with a new convert cmd", err), - // )) - //} - // - //savePartialTx = !isFullySigned && err == nil - //ux.Logger.PrintToUser("ConvertSubnetTx ID: %s", convertSubnetTxID) - // - //if savePartialTx { - // if err := SaveNotFullySignedTx( - // "ConvertSubnetTx", - // tx, - // chain, - // subnetAuthKeys, - // remainingSubnetAuthKeys, - // outputTxPath, - // false, - // ); err != nil { - // return err - // } - //} - // - //flags := make(map[string]string) - //flags[constants.MetricsNetwork] = network.Name() - //metrics.HandleTracking(cmd, constants.MetricsSubnetDeployCommand, app, flags) - // - //// update sidecar - //// TODO: need to do something for backwards compatibility? - //return app.UpdateSidecarNetworks(&sidecar, network, subnetID, blockchainID, "", "", bootstrapValidators) - return nil -} diff --git a/cmd/blockchaincmd/create.go b/cmd/blockchaincmd/create.go index 065d45557..5736b2e22 100644 --- a/cmd/blockchaincmd/create.go +++ b/cmd/blockchaincmd/create.go @@ -110,7 +110,7 @@ configuration, pass the -f flag.`, cmd.Flags().BoolVar(&createFlags.proofOfAuthority, "proof-of-authority", false, "use proof of authority for validator management") cmd.Flags().BoolVar(&createFlags.proofOfStake, "proof-of-stake", false, "(coming soon) use proof of stake for validator management") cmd.Flags().StringVar(&createFlags.poaValidatorManagerOwner, "poa-manager-owner", "", "EVM address that controls Validator Manager Owner (for Proof of Authority only)") - cmd.Flags().BoolVar(&nonSOV, "not-sov", false, "set to true if creating non-SOV (Subnet Only Validator) blockchain") + cmd.Flags().BoolVar(&sovereign, "sovereign", true, "set to false if creating non-sovereign blockchain") return cmd } @@ -195,7 +195,7 @@ func createBlockchainConfig(cmd *cobra.Command, args []string) error { return errors.New("flags --evm,--custom are mutually exclusive") } - if nonSOV { + if !sovereign { if createFlags.proofOfAuthority || createFlags.proofOfStake || createFlags.poaValidatorManagerOwner != "" { return errSOVFlagsOnly } @@ -232,7 +232,7 @@ func createBlockchainConfig(cmd *cobra.Command, args []string) error { sc := &models.Sidecar{} - if !nonSOV { + if sovereign { if err = promptValidatorManagementType(app, sc); err != nil { return err } @@ -242,7 +242,7 @@ func createBlockchainConfig(cmd *cobra.Command, args []string) error { } if vmType == models.SubnetEvm { - if !nonSOV { + if sovereign { if sc.PoA() { if createFlags.poaValidatorManagerOwner == "" { createFlags.poaValidatorManagerOwner, err = getValidatorContractManagerAddr() @@ -335,7 +335,7 @@ func createBlockchainConfig(cmd *cobra.Command, args []string) error { vmVersion, tokenSymbol, true, - nonSOV, + sovereign, ); err != nil { return err } @@ -365,7 +365,7 @@ func createBlockchainConfig(cmd *cobra.Command, args []string) error { customVMBuildScript, vmFile, tokenSymbol, - nonSOV, + sovereign, ); err != nil { return err } diff --git a/cmd/blockchaincmd/deploy.go b/cmd/blockchaincmd/deploy.go index 1c2ae5b5e..71277b313 100644 --- a/cmd/blockchaincmd/deploy.go +++ b/cmd/blockchaincmd/deploy.go @@ -64,7 +64,7 @@ var ( useLedger bool useEwoq bool ledgerAddresses []string - nonSOV bool + sovereign bool subnetIDStr string mainnetChainID uint32 skipCreatePrompt bool @@ -346,8 +346,8 @@ func deployBlockchain(cmd *cobra.Command, args []string) error { } } - if sidecar.NotSOV && bootstrapValidatorsJSONFilePath != "" { - return fmt.Errorf("--bootstrap-filepath flag is only applicable to SOV (Subnet Only Validator) blockchains") + if !sidecar.Sovereign && bootstrapValidatorsJSONFilePath != "" { + return fmt.Errorf("--bootstrap-filepath flag is only applicable to sovereign blockchains") } network, err := networkoptions.GetNetworkFromCmdLineFlags( @@ -394,7 +394,7 @@ func deployBlockchain(cmd *cobra.Command, args []string) error { } } - if !sidecar.NotSOV { + if sidecar.Sovereign { if bootstrapValidatorsJSONFilePath == "" { bootstrapValidators, err = promptBootstrapValidators(network) if err != nil { @@ -509,7 +509,7 @@ func deployBlockchain(cmd *cobra.Command, args []string) error { network.HandlePublicNetworkSimulation() if createSubnet { - if !sidecar.NotSOV { + if sidecar.Sovereign { sameControlKey = true } controlKeys, threshold, err = promptOwners( @@ -619,8 +619,8 @@ func deployBlockchain(cmd *cobra.Command, args []string) error { } } - if !sidecar.NotSOV { - avaGoBootstrapValidators, err := ConvertToAvalancheGoSubnetValidator(bootstrapValidators) + if sidecar.Sovereign { + avaGoBootstrapValidators, err := convertToAvalancheGoSubnetValidator(bootstrapValidators) if err != nil { return err } diff --git a/cmd/blockchaincmd/remove_validator.go b/cmd/blockchaincmd/remove_validator.go index 5fe8ed3d3..c903066ae 100644 --- a/cmd/blockchaincmd/remove_validator.go +++ b/cmd/blockchaincmd/remove_validator.go @@ -34,7 +34,7 @@ var removeValidatorSupportedNetworkOptions = []networkoptions.NetworkOption{ // avalanche blockchain removeValidator func newRemoveValidatorCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "removeValidator [blockchainName] [nodeID]", + Use: "removeValidator [blockchainName]", Short: "Remove a permissioned validator from your blockchain's subnet", Long: `The blockchain removeValidator command stops a whitelisted, subnet network validator from validating your deployed Blockchain. @@ -42,7 +42,7 @@ validating your deployed Blockchain. To remove the validator from the Subnet's allow list, provide the validator's unique NodeID. You can bypass these prompts by providing the values with flags.`, RunE: removeValidator, - Args: cobrautils.ExactArgs(2), + Args: cobrautils.ExactArgs(1), } networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, removeValidatorSupportedNetworkOptions) cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji deploy only]") @@ -50,7 +50,8 @@ these prompts by providing the values with flags.`, cmd.Flags().StringVar(&outputTxPath, "output-tx-path", "", "(for non-SOV blockchain only) file path of the removeValidator tx") cmd.Flags().BoolVarP(&useLedger, "ledger", "g", false, "use ledger instead of key (always true on mainnet, defaults to false on fuji)") cmd.Flags().StringSliceVar(&ledgerAddresses, "ledger-addrs", []string{}, "use the given ledger addresses") - cmd.Flags().BoolVar(&nonSOV, "not-sov", false, "set to true if removing validator in a non-SOV blockchain") + cmd.Flags().StringVar(&nodeIDStr, "node-id", "", "node-id of the validator") + cmd.Flags().BoolVar(&sovereign, "sovereign", true, "set to false if removing validator in a non-sovereign blockchain") return cmd } @@ -75,7 +76,7 @@ func removeValidator(_ *cobra.Command, args []string) error { return err } - if nonSOV { + if !sovereign { if outputTxPath != "" { return errors.New("--output-tx-path flag cannot be used for non-SOV (Subnet-Only Validators) blockchains") } @@ -106,7 +107,7 @@ func removeValidator(_ *cobra.Command, args []string) error { switch network.Kind { case models.Local: - if nonSOV { + if !sovereign { return removeFromLocalNonSOV(blockchainName) } case models.Devnet: @@ -151,10 +152,19 @@ func removeValidator(_ *cobra.Command, args []string) error { return errNoSubnetID } - nodeID, err := ids.NodeIDFromString(nodeIDStr) - if err != nil { - return err + var nodeID ids.NodeID + if nodeIDStr == "" { + nodeID, err = PromptNodeID("remove as a blockchain validator") + if err != nil { + return err + } + } else { + nodeID, err = ids.NodeIDFromString(nodeIDStr) + if err != nil { + return err + } } + // check that this guy actually is a validator on the subnet isValidator, err := subnet.IsSubnetValidator(subnetID, nodeID, network) if err != nil { @@ -166,7 +176,7 @@ func removeValidator(_ *cobra.Command, args []string) error { } deployer := subnet.NewPublicDeployer(app, kc, network) - if nonSOV { + if !sovereign { return removeValidatorNonSOV(deployer, network, subnetID, kc, blockchainName, nodeID) } return removeValidatorSOV(deployer, network, subnetID, nodeID) diff --git a/pkg/models/sidecar.go b/pkg/models/sidecar.go index 7ea84ecdc..502766a4d 100644 --- a/pkg/models/sidecar.go +++ b/pkg/models/sidecar.go @@ -45,8 +45,8 @@ type Sidecar struct { // TODO: remove if not needed for subnet acp 77 create flow once avalnache go releases etna ValidatorManagement ValidatorManagementType PoAValidatorManagerOwner string - // Subnet defaults to SOV post ACP-77 - NotSOV bool + // Subnet defaults to Sovereign post ACP-77 + Sovereign bool } func (sc Sidecar) GetVMID() (string, error) { diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 34c94dbef..94af78ac8 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -258,7 +258,7 @@ func (*realPrompter) CaptureID(promptStr string) (ids.ID, error) { func (*realPrompter) CaptureNodeID(promptStr string) (ids.NodeID, error) { prompt := promptui.Prompt{ Label: promptStr, - Validate: validateNodeID, + Validate: ValidateNodeID, } nodeIDStr, err := prompt.Run() diff --git a/pkg/prompts/validations.go b/pkg/prompts/validations.go index 5b541c7d2..860cec0c0 100644 --- a/pkg/prompts/validations.go +++ b/pkg/prompts/validations.go @@ -83,7 +83,7 @@ func validateTime(input string) error { return err } -func validateNodeID(input string) error { +func ValidateNodeID(input string) error { _, err := ids.NodeIDFromString(input) return err } @@ -134,8 +134,8 @@ func validateValidatorBalance(input string) error { if err != nil { return err } - if val == 0 { - return fmt.Errorf("subnet validator balance must be greater than 0 AVAX") + if val < 1 { + return fmt.Errorf("subnet validator balance must be at least 1 AVAX") } return nil } diff --git a/pkg/subnet/public.go b/pkg/subnet/public.go index 581c17a23..3f717f723 100644 --- a/pkg/subnet/public.go +++ b/pkg/subnet/public.go @@ -119,30 +119,9 @@ func (d *PublicDeployer) AddValidatorNonSOV( return false, tx, remainingSubnetAuthKeys, nil } -// type SetSubnetValidatorWeightTx struct { -// // Metadata, inputs and outputs -// BaseTx -// // AddressedCall with Payload: -// // - ValidationID (SHA256 of the AddressedCall Payload of the RegisterSubnetValidatorTx adding the validator) -// // - Nonce -// // - Weight -// Message warp.Message `json:"message"` -// } func (d *PublicDeployer) SetL1ValidatorWeight( message warp.Message, ) (*txs.Tx, error) { - // create tx - //unsignedTx, err := wallet.P().Builder().NewSetL1ValidatorWeightTx(args...) - //if err != nil { - // return nil, fmt.Errorf("error building tx: %w", err) - //} - //tx := txs.Tx{Unsigned: unsignedTx} - // sign with current wallet that contains EVM address controlling POA Validator Manager - // TODO: change code below - //if err := wallet.P().Signer().Sign(context.Background(), &tx); err != nil { - // return nil, fmt.Errorf("error signing tx: %w", err) - //} - //return &tx, nil return nil, nil } @@ -152,18 +131,6 @@ func (d *PublicDeployer) RegisterL1Validator( changeOwner fx.Owner, message warp.Message, ) (*txs.Tx, error) { - // create tx - //unsignedTx, err := wallet.P().Builder().NewRegisterL1ValidatorTx(args...) - //if err != nil { - // return nil, fmt.Errorf("error building tx: %w", err) - //} - //tx := txs.Tx{Unsigned: unsignedTx} - // sign with current wallet that contains EVM address controlling POA Validator Manager - // TODO: change code below - //if err := wallet.P().Signer().Sign(context.Background(), &tx); err != nil { - // return nil, fmt.Errorf("error signing tx: %w", err) - //} - //return &tx, nil return nil, nil } diff --git a/pkg/vm/create_custom.go b/pkg/vm/create_custom.go index e00a80159..536c623a1 100644 --- a/pkg/vm/create_custom.go +++ b/pkg/vm/create_custom.go @@ -26,7 +26,7 @@ func CreateCustomSidecar( customVMBuildScript string, vmPath string, tokenSymbol string, - nonSov bool, + sovereign bool, ) (*models.Sidecar, error) { ux.Logger.PrintToUser("creating custom VM subnet %s", subnetName) @@ -83,7 +83,7 @@ func CreateCustomSidecar( } sc.RPCVersion = rpcVersion - sc.NotSOV = nonSov + sc.Sovereign = sovereign return sc, nil } diff --git a/pkg/vm/create_evm.go b/pkg/vm/create_evm.go index a7315d61e..417de5f53 100644 --- a/pkg/vm/create_evm.go +++ b/pkg/vm/create_evm.go @@ -38,7 +38,7 @@ func CreateEvmSidecar( subnetEVMVersion string, tokenSymbol string, getRPCVersionFromBinary bool, - notSov bool, + sovereign bool, ) (*models.Sidecar, error) { var ( err error @@ -72,7 +72,7 @@ func CreateEvmSidecar( sc.Subnet = subnetName sc.TokenSymbol = tokenSymbol sc.TokenName = tokenSymbol + " Token" - sc.NotSOV = notSov + sc.Sovereign = sovereign return sc, nil } diff --git a/tests/e2e/commands/subnet.go b/tests/e2e/commands/subnet.go index c564a0cd0..2f6639a15 100644 --- a/tests/e2e/commands/subnet.go +++ b/tests/e2e/commands/subnet.go @@ -54,7 +54,7 @@ func CreateSubnetEvmConfigWithVersionNonSOV(subnetName string, genesisPath strin "create", "--genesis", genesisPath, - "--not-sov", + "--sovereign=false", "--evm", subnetName, "--" + constants.SkipUpdateFlag, @@ -178,7 +178,7 @@ func CreateCustomVMConfigNonSOV(subnetName string, genesisPath string, vmPath st "create", "--genesis", genesisPath, - "--not-sov", + "--sovereign=false", "--custom", subnetName, "--custom-vm-path",