From 4aa2ac138e75053d7170f6ed1490677e4e8e2304 Mon Sep 17 00:00:00 2001 From: felipemadero Date: Tue, 14 Jan 2025 16:50:53 -0300 Subject: [PATCH] Improve change weight (#2545) * improve change weight * partial work * implemented! * move functions to SDK * nit * make all balances float * use sdk network object on sdk functions * reduce dep on pkg from sdk helper * address PR comment * mv functions to validator SDK package * address PR comments --- cmd/blockchaincmd/add_validator.go | 69 ++++-- cmd/blockchaincmd/change_owner.go | 11 +- cmd/blockchaincmd/change_weight.go | 228 +++++++++++------- cmd/blockchaincmd/deploy.go | 14 +- cmd/blockchaincmd/helpers.go | 6 +- cmd/blockchaincmd/import_public.go | 10 +- cmd/blockchaincmd/join.go | 10 +- cmd/blockchaincmd/remove_validator.go | 12 +- cmd/blockchaincmd/stats.go | 11 +- cmd/blockchaincmd/validators.go | 11 +- cmd/contractcmd/deploy_erc20.go | 13 +- cmd/contractcmd/init_validator_manager.go | 10 +- cmd/interchaincmd/messengercmd/deploy.go | 13 +- cmd/interchaincmd/messengercmd/send_msg.go | 13 +- cmd/interchaincmd/relayercmd/deploy.go | 13 +- cmd/interchaincmd/relayercmd/logs.go | 3 +- .../tokentransferrercmd/deploy.go | 13 +- cmd/keycmd/list.go | 48 ++-- cmd/keycmd/transfer.go | 10 +- cmd/nodecmd/create.go | 5 +- cmd/nodecmd/local.go | 10 +- cmd/nodecmd/validate_primary.go | 2 +- cmd/primarycmd/add_validator.go | 11 +- cmd/primarycmd/describe.go | 6 +- cmd/validatorcmd/getBalance.go | 22 +- cmd/validatorcmd/increaseBalance.go | 33 +-- cmd/validatorcmd/list.go | 18 +- internal/mocks/prompter.go | 42 ++-- pkg/constants/constants.go | 2 + pkg/contract/contract.go | 4 +- pkg/models/network.go | 18 +- pkg/networkoptions/network_options.go | 23 ++ pkg/node/helper.go | 3 +- pkg/prompts/prompts.go | 29 ++- pkg/prompts/validations.go | 8 +- pkg/txutils/info.go | 10 - pkg/utils/common.go | 9 - pkg/validatormanager/registration.go | 46 +--- pkg/validatormanager/removal.go | 19 +- pkg/vm/allowlist.go | 9 +- pkg/vm/precompiles.go | 9 +- sdk/utils/utils.go | 9 + sdk/validator/validator.go | 92 +++++++ 43 files changed, 510 insertions(+), 447 deletions(-) create mode 100644 sdk/validator/validator.go diff --git a/cmd/blockchaincmd/add_validator.go b/cmd/blockchaincmd/add_validator.go index 229db1b6a..5b1afabba 100644 --- a/cmd/blockchaincmd/add_validator.go +++ b/cmd/blockchaincmd/add_validator.go @@ -27,6 +27,7 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" "github.com/ava-labs/avalanche-cli/pkg/validatormanager" + "github.com/ava-labs/avalanche-cli/sdk/validator" "github.com/ava-labs/avalanchego/ids" avagoconstants "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/formatting/address" @@ -37,16 +38,9 @@ import ( ) var ( - addValidatorSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, - } - nodeIDStr string nodeEndpoint string - balance uint64 + balanceAVAX float64 weight uint64 startTimeStr string duration time.Duration @@ -92,11 +86,16 @@ Testnet or Mainnet.`, RunE: addValidator, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, addValidatorSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji/devnet only]") cmd.Flags().Uint64Var(&weight, "weight", constants.NonBootstrapValidatorWeight, "set the staking weight of the validator to add") - cmd.Flags().Uint64Var(&balance, "balance", 0, "set the AVAX balance of the validator that will be used for continuous fee on P-Chain") + cmd.Flags().Float64Var( + &balanceAVAX, + "balance", + 0, + "set the AVAX balance of the validator that will be used for continuous fee on P-Chain", + ) 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") @@ -151,14 +150,13 @@ func addValidator(_ *cobra.Command, args []string) error { return fmt.Errorf("failed to load sidecar: %w", err) } - networkOptionsList := networkoptions.GetNetworkFromSidecar(sc, addValidatorSupportedNetworkOptions) network, err := networkoptions.GetNetworkFromCmdLineFlags( app, "", globalNetworkFlags, true, false, - networkOptionsList, + networkoptions.GetNetworkFromSidecar(sc, networkoptions.DefaultSupportedNetworkOptions), "", ) if err != nil { @@ -219,6 +217,8 @@ func addValidator(_ *cobra.Command, args []string) error { } } + subnetID := sc.Networks[network.Name()].SubnetID + // if user chose to upsize a local node to add another local validator if createLocalValidator { anrSettings := node.ANRSettings{} @@ -240,7 +240,6 @@ func addValidator(_ *cobra.Command, args []string) error { nodeName := "" blockchainID := sc.Networks[network.Name()].BlockchainID - subnetID := sc.Networks[network.Name()].SubnetID if nodeName, err = node.UpsizeLocalNode( app, @@ -303,10 +302,23 @@ func addValidator(_ *cobra.Command, args []string) error { if !sovereign { return CallAddValidatorNonSOV(deployer, network, kc, useLedger, blockchainName, nodeIDStr, defaultValidatorParams, waitForTxAcceptance) } - return CallAddValidator(deployer, network, kc, blockchainName, nodeIDStr, publicKey, pop) + return CallAddValidator( + deployer, + network, + kc, + blockchainName, + subnetID, + nodeIDStr, + publicKey, + pop, + weight, + balanceAVAX, + remainingBalanceOwnerAddr, + disableOwnerAddr, + ) } -func promptValidatorBalance(availableBalance uint64) (uint64, error) { +func promptValidatorBalanceAVAX(availableBalance float64) (float64, error) { ux.Logger.PrintToUser("Validator's balance is used to pay for continuous fee to the P-Chain") ux.Logger.PrintToUser("When this Balance reaches 0, the validator will be considered inactive and will no longer participate in validating the L1") txt := "What balance would you like to assign to the validator (in AVAX)?" @@ -318,9 +330,14 @@ func CallAddValidator( network models.Network, kc *keychain.Keychain, blockchainName string, + subnetID ids.ID, nodeIDStr string, publicKey string, pop string, + weight uint64, + balanceAVAX float64, + remainingBalanceOwnerAddr string, + disableOwnerAddr string, ) error { nodeID, err := ids.NodeIDFromString(nodeIDStr) if err != nil { @@ -401,19 +418,27 @@ func CallAddValidator( ux.Logger.PrintToUser(logging.Yellow.Wrap("RPC Endpoint: %s"), rpcURL) - if balance == 0 { + totalWeight, err := validator.GetTotalWeight(network.SDKNetwork(), subnetID) + if err != nil { + return err + } + allowedChange := float64(totalWeight) * constants.MaxL1TotalWeightChange + if float64(weight) > allowedChange { + return fmt.Errorf("can't make change: desired validator weight %d exceeds max allowed weight change of %d", newWeight, uint64(allowedChange)) + } + + if balanceAVAX == 0 { availableBalance, err := utils.GetNetworkBalance(kc.Addresses().List(), network.Endpoint) if err != nil { return err } - balance, err = promptValidatorBalance(availableBalance / units.Avax) + balanceAVAX, err = promptValidatorBalanceAVAX(float64(availableBalance) / float64(units.Avax)) if err != nil { return err } - } else { - // convert to nanoAVAX - balance *= units.Avax } + // convert to nanoAVAX + balance := uint64(balanceAVAX * float64(units.Avax)) if remainingBalanceOwnerAddr == "" { remainingBalanceOwnerAddr, err = getKeyForChangeOwner(network) @@ -529,7 +554,7 @@ func CallAddValidator( if !pos { ux.Logger.PrintToUser(" Weight: %d", weight) } - ux.Logger.PrintToUser(" Balance: %d", balance/units.Avax) + ux.Logger.PrintToUser(" Balance: %.2f", balanceAVAX) ux.Logger.GreenCheckmarkToUser("Validator successfully added to the L1") return nil @@ -818,7 +843,7 @@ func getWeight() (uint64, error) { case defaultWeight: useDefaultWeight = true default: - weight, err = app.Prompt.CaptureWeight(txt) + weight, err = app.Prompt.CaptureWeight(txt, func(uint64) error { return nil }) if err != nil { return 0, err } diff --git a/cmd/blockchaincmd/change_owner.go b/cmd/blockchaincmd/change_owner.go index 5dd6de0e8..4bcab5f73 100644 --- a/cmd/blockchaincmd/change_owner.go +++ b/cmd/blockchaincmd/change_owner.go @@ -18,13 +18,6 @@ import ( "github.com/spf13/cobra" ) -var changeOwnerSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, -} - // avalanche blockchain changeOwner func newChangeOwnerCmd() *cobra.Command { cmd := &cobra.Command{ @@ -34,7 +27,7 @@ func newChangeOwnerCmd() *cobra.Command { RunE: changeOwner, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, changeOwnerSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions) 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(&keyName, "key", "k", "", "select the key to use [fuji/devnet]") @@ -56,7 +49,7 @@ func changeOwner(_ *cobra.Command, args []string) error { globalNetworkFlags, true, false, - changeOwnerSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/blockchaincmd/change_weight.go b/cmd/blockchaincmd/change_weight.go index 91452b634..33e54e143 100644 --- a/cmd/blockchaincmd/change_weight.go +++ b/cmd/blockchaincmd/change_weight.go @@ -3,22 +3,30 @@ 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/contract" + "github.com/ava-labs/avalanche-cli/pkg/key" "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/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" + "github.com/ava-labs/avalanche-cli/sdk/validator" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/formatting" + "github.com/ava-labs/avalanchego/utils/formatting/address" + "github.com/ava-labs/avalanchego/utils/units" "github.com/spf13/cobra" ) +var newWeight uint64 + // avalanche blockchain addValidator func newChangeWeightCmd() *cobra.Command { cmd := &cobra.Command{ @@ -30,12 +38,13 @@ The L1 has to be a Proof of Authority L1.`, RunE: setWeight, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, addValidatorSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji/devnet only]") - cmd.Flags().Uint64Var(&weight, "weight", constants.NonBootstrapValidatorWeight, "set the new staking weight of the validator") + cmd.Flags().Uint64Var(&newWeight, "weight", 0, "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().StringVar(&nodeEndpoint, "node-endpoint", "", "gather node id/bls from publicly available avalanchego apis on the given endpoint") 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,17 +52,13 @@ The L1 has to be a Proof of Authority L1.`, func setWeight(_ *cobra.Command, args []string) error { blockchainName := args[0] - err := prompts.ValidateNodeID(nodeIDStr) - if err != nil { - return err - } sc, err := app.LoadSidecar(blockchainName) if err != nil { return fmt.Errorf("failed to load sidecar: %w", err) } - networkOptionsList := networkoptions.GetNetworkFromSidecar(sc, removeValidatorSupportedNetworkOptions) + networkOptionsList := networkoptions.GetNetworkFromSidecar(sc, networkoptions.DefaultSupportedNetworkOptions) network, err := networkoptions.GetNetworkFromCmdLineFlags( app, "", @@ -67,47 +72,17 @@ func setWeight(_ *cobra.Command, args []string) error { return err } - if outputTxPath != "" { - if _, err := os.Stat(outputTxPath); err == nil { - return fmt.Errorf("outputTxPath %q already exists", outputTxPath) - } - } - - if len(ledgerAddresses) > 0 { - useLedger = true - } - - if useLedger && keyName != "" { - return ErrMutuallyExlusiveKeyLedger - } - - switch network.Kind { - case models.Devnet: - if !useLedger && keyName == "" { - useLedger, keyName, err = prompts.GetKeyOrLedger(app.Prompt, constants.PayTxsFeesMsg, app.GetKeyDir(), false) - if err != nil { - return err - } - } - case models.Fuji: - if !useLedger && keyName == "" { - useLedger, keyName, err = prompts.GetKeyOrLedger(app.Prompt, constants.PayTxsFeesMsg, app.GetKeyDir(), false) - if err != nil { - return err - } - } - case models.Mainnet: - useLedger = true - if keyName != "" { - return ErrStoredKeyOnMainnet - } - default: - return errors.New("unsupported network") - } - - // get keychain accesor fee := network.GenesisParams().TxFeeConfig.StaticFeeConfig.TxFee - kc, err := keychain.GetKeychain(app, false, useLedger, ledgerAddresses, keyName, network, fee) + kc, err := keychain.GetKeychainFromCmdLineFlags( + app, + "to pay for transaction fees on P-Chain", + network, + keyName, + useEwoq, + useLedger, + ledgerAddresses, + fee, + ) if err != nil { return err } @@ -119,20 +94,30 @@ func setWeight(_ *cobra.Command, args []string) error { return errNoSubnetID } + if nodeEndpoint != "" { + nodeIDStr, publicKey, pop, err = node.GetNodeData(nodeEndpoint) + if err != nil { + return err + } + } + var nodeID ids.NodeID if nodeIDStr == "" { - nodeID, err = PromptNodeID("add as a blockchain validator") + nodeID, err = PromptNodeID("change weight") if err != nil { return err } } else { + if err := prompts.ValidateNodeID(nodeIDStr); err != nil { + return err + } nodeID, err = ids.NodeIDFromString(nodeIDStr) if err != nil { return err } } - isValidator, err := subnet.IsSubnetValidator(subnetID, nodeID, network) + isValidator, err := validator.IsValidator(network.SDKNetwork(), subnetID, nodeID) if err != nil { // just warn the user, don't fail ux.Logger.PrintToUser("failed to check if node is a validator: %s", err) @@ -141,59 +126,132 @@ func setWeight(_ *cobra.Command, args []string) error { return fmt.Errorf("node %s is not a validator for blockchain %s", nodeID, subnetID) } - deployer := subnet.NewPublicDeployer(app, kc, network) + chainSpec := contract.ChainSpec{ + BlockchainName: blockchainName, + } - // first remove the validator from subnet - err = removeValidatorSOV(deployer, - network, - blockchainName, - nodeID, - 0, // automatic uptime - isBootstrapValidatorForNetwork(nodeID, sc.Networks[network.Name()]), - false, // don't force - ) + if rpcURL == "" { + rpcURL, _, err = contract.GetBlockchainEndpoints( + app, + network, + chainSpec, + true, + false, + ) + if err != nil { + return err + } + } + + validationID, err := validator.GetValidationID(rpcURL, nodeID) if err != nil { return err } - // TODO: we need to wait for the balance from the removed validator to arrive in changeAddr - // set arbitrary time.sleep here? - - weight, err = app.Prompt.CaptureWeight("What weight would you like to assign to the validator?") + validatorInfo, err := validator.GetValidatorInfo(network.SDKNetwork(), validationID) if err != nil { return err } - balance, err = getValidatorBalanceFromPChain() + totalWeight, err := validator.GetTotalWeight(network.SDKNetwork(), subnetID) if err != nil { return err } - publicKey, pop, err = getBLSInfoFromPChain() + allowedChange := float64(totalWeight) * constants.MaxL1TotalWeightChange + + if float64(validatorInfo.Weight) > allowedChange { + return fmt.Errorf("can't make change: current validator weight %d exceeds max allowed weight change of %d", validatorInfo.Weight, uint64(allowedChange)) + } + + allowedChange = float64(totalWeight-validatorInfo.Weight) * constants.MaxL1TotalWeightChange + + if newWeight == 0 { + ux.Logger.PrintToUser("Current validator weight is %d", validatorInfo.Weight) + newWeight, err = app.Prompt.CaptureWeight( + "What weight would you like to assign to the validator?", + func(v uint64) error { + if v > uint64(allowedChange) { + return fmt.Errorf("weight exceeds max allowed weight change of %d", uint64(allowedChange)) + } + return nil + }, + ) + if err != nil { + return err + } + } + + if float64(newWeight) > allowedChange { + return fmt.Errorf("can't make change: desired validator weight %d exceeds max allowed weight change of %d", newWeight, uint64(allowedChange)) + } + + publicKey, err = formatting.Encode(formatting.HexNC, bls.PublicKeyToCompressedBytes(validatorInfo.PublicKey)) if err != nil { return err } - remainingBalanceOwnerAddr, err = getChangeAddrFromPChain() - if err != nil { - return fmt.Errorf("failure parsing change owner address: %w", err) + if pop == "" { + _, pop, err = promptProofOfPossession(false, true) + if err != nil { + return err + } } - // add back validator to subnet with updated weight - return CallAddValidator(deployer, network, kc, blockchainName, nodeID.String(), publicKey, pop) -} + deployer := subnet.NewPublicDeployer(app, kc, network) -// getValidatorBalanceFromPChain gets remaining balance of validator from p chain -func getValidatorBalanceFromPChain() (uint64, error) { - return 0, nil -} + var remainingBalanceOwnerAddr, disableOwnerAddr string + hrp := key.GetHRP(network.ID) + if validatorInfo.RemainingBalanceOwner != nil && len(validatorInfo.RemainingBalanceOwner.Addrs) > 0 { + remainingBalanceOwnerAddr, err = address.Format("P", hrp, validatorInfo.RemainingBalanceOwner.Addrs[0][:]) + if err != nil { + return err + } + } + if validatorInfo.DeactivationOwner != nil && len(validatorInfo.DeactivationOwner.Addrs) > 0 { + disableOwnerAddr, err = address.Format("P", hrp, validatorInfo.DeactivationOwner.Addrs[0][:]) + if err != nil { + return err + } + } -// getBLSInfoFromPChain gets BLS public key and pop from info api -func getBLSInfoFromPChain() (string, string, error) { - return "", "", nil -} + // first remove the validator from subnet + err = removeValidatorSOV( + deployer, + network, + blockchainName, + nodeID, + 0, // automatic uptime + isBootstrapValidatorForNetwork(nodeID, sc.Networks[network.Name()]), + false, // don't force + ) + if err != nil { + return err + } -// getChangeAddrFromPChain gets validator change addr from info api -func getChangeAddrFromPChain() (string, error) { - return "", nil + balance := validatorInfo.Balance + if validatorInfo.RemainingBalanceOwner != nil && len(validatorInfo.RemainingBalanceOwner.Addrs) > 0 { + availableBalance, err := utils.GetNetworkBalance([]ids.ShortID{validatorInfo.RemainingBalanceOwner.Addrs[0]}, network.Endpoint) + if err != nil { + ux.Logger.RedXToUser("failure checking remaining balance of validator: %s. continuing with default value", err) + } else if availableBalance < balance { + balance = availableBalance + } + } + + // add back validator to subnet with updated weight + return CallAddValidator( + deployer, + network, + kc, + blockchainName, + subnetID, + nodeID.String(), + publicKey, + pop, + newWeight, + float64(balance)/float64(units.Avax), + remainingBalanceOwnerAddr, + disableOwnerAddr, + ) } diff --git a/cmd/blockchaincmd/deploy.go b/cmd/blockchaincmd/deploy.go index 2321f55b9..309236cf0 100644 --- a/cmd/blockchaincmd/deploy.go +++ b/cmd/blockchaincmd/deploy.go @@ -57,13 +57,6 @@ import ( const skipRelayerFlagName = "skip-relayer" -var deploySupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, -} - var ( sameControlKey bool keyName string @@ -133,7 +126,7 @@ so you can take your locally tested Blockchain and deploy it on Fuji or Mainnet. PersistentPostRun: handlePostRun, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, deploySupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions) privateKeyFlags.SetFlagNames("blockchain-private-key", "blockchain-key", "blockchain-genesis-key") privateKeyFlags.AddToCmd(cmd, "to fund validator manager initialization") cmd.Flags().StringVar( @@ -311,9 +304,8 @@ func checkSubnetEVMDefaultAddressNotInAlloc(network models.Network, chain string return nil } -func runDeploy(cmd *cobra.Command, args []string, supportedNetworkOptions []networkoptions.NetworkOption) error { +func runDeploy(cmd *cobra.Command, args []string) error { skipCreatePrompt = true - deploySupportedNetworkOptions = supportedNetworkOptions return deployBlockchain(cmd, args) } @@ -449,7 +441,7 @@ func deployBlockchain(cmd *cobra.Command, args []string) error { globalNetworkFlags, true, false, - deploySupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/blockchaincmd/helpers.go b/cmd/blockchaincmd/helpers.go index 7d218d7ca..08a9e1e44 100644 --- a/cmd/blockchaincmd/helpers.go +++ b/cmd/blockchaincmd/helpers.go @@ -36,7 +36,7 @@ func CreateBlockchainFirst(cmd *cobra.Command, blockchainName string, skipPrompt return nil } -func DeployBlockchainFirst(cmd *cobra.Command, blockchainName string, skipPrompt bool, supportedNetworkOptions []networkoptions.NetworkOption) error { +func DeployBlockchainFirst(cmd *cobra.Command, blockchainName string, skipPrompt bool) error { var ( doDeploy bool msg string @@ -47,7 +47,7 @@ func DeployBlockchainFirst(cmd *cobra.Command, blockchainName string, skipPrompt msg = fmt.Sprintf("Blockchain %s is not created yet. Do you want to create it first?", blockchainName) errIfNoChoosen = fmt.Errorf("blockchain not available and not being created first") } else { - filteredSupportedNetworkOptions, _, _, err := networkoptions.GetSupportedNetworkOptionsForSubnet(app, blockchainName, supportedNetworkOptions) + filteredSupportedNetworkOptions, _, _, err := networkoptions.GetSupportedNetworkOptionsForSubnet(app, blockchainName, networkoptions.DefaultSupportedNetworkOptions) if err != nil { return err } @@ -67,7 +67,7 @@ func DeployBlockchainFirst(cmd *cobra.Command, blockchainName string, skipPrompt return errIfNoChoosen } } - return runDeploy(cmd, []string{blockchainName}, supportedNetworkOptions) + return runDeploy(cmd, []string{blockchainName}) } return nil } diff --git a/cmd/blockchaincmd/import_public.go b/cmd/blockchaincmd/import_public.go index 519685ea9..d1386bb6f 100644 --- a/cmd/blockchaincmd/import_public.go +++ b/cmd/blockchaincmd/import_public.go @@ -22,12 +22,6 @@ import ( ) var ( - importPublicSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Fuji, - networkoptions.Mainnet, - networkoptions.Devnet, - networkoptions.Local, - } blockchainIDstr string nodeURL string useSubnetEvm bool @@ -48,7 +42,7 @@ doesn't overwrite an existing Blockchain with the same name. To allow overwrites flag.`, } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, importPublicSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVar(&nodeURL, "node-url", "", "[optional] URL of an already running validator") @@ -76,7 +70,7 @@ func importPublic(*cobra.Command, []string) error { globalNetworkFlags, true, false, - importPublicSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/blockchaincmd/join.go b/cmd/blockchaincmd/join.go index a6b8b0f5a..c09181693 100644 --- a/cmd/blockchaincmd/join.go +++ b/cmd/blockchaincmd/join.go @@ -23,12 +23,6 @@ import ( ) var ( - joinSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, - } // path to avalanchego config file avagoConfigPath string // path to avalanchego plugin dir @@ -65,7 +59,7 @@ This command currently only supports Blockchains deployed on the Fuji Testnet an RunE: joinCmd, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, joinSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVar(&avagoConfigPath, "avalanchego-config", "", "file path of the avalanchego config file") cmd.Flags().StringVar(&pluginDir, "plugin-dir", "", "file path of avalanchego's plugin directory") cmd.Flags().StringVar(&dataDir, "data-dir", "", "path of avalanchego's data dir directory") @@ -108,7 +102,7 @@ func joinCmd(_ *cobra.Command, args []string) error { globalNetworkFlags, true, false, - joinSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/blockchaincmd/remove_validator.go b/cmd/blockchaincmd/remove_validator.go index 146549803..f288c7024 100644 --- a/cmd/blockchaincmd/remove_validator.go +++ b/cmd/blockchaincmd/remove_validator.go @@ -32,13 +32,6 @@ import ( "github.com/spf13/cobra" ) -var removeValidatorSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, -} - var ( uptimeSec uint64 force bool @@ -57,7 +50,7 @@ these prompts by providing the values with flags.`, RunE: removeValidator, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, removeValidatorSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji deploy only]") cmd.Flags().StringSliceVar(&subnetAuthKeys, "auth-keys", nil, "(for non-SOV blockchain only) control keys that will be used to authenticate the removeValidator tx") cmd.Flags().StringVar(&outputTxPath, "output-tx-path", "", "(for non-SOV blockchain only) file path of the removeValidator tx") @@ -88,14 +81,13 @@ func removeValidator(_ *cobra.Command, args []string) error { return err } - networkOptionsList := networkoptions.GetNetworkFromSidecar(sc, removeValidatorSupportedNetworkOptions) network, err := networkoptions.GetNetworkFromCmdLineFlags( app, "", globalNetworkFlags, true, false, - networkOptionsList, + networkoptions.GetNetworkFromSidecar(sc, networkoptions.DefaultSupportedNetworkOptions), "", ) if err != nil { diff --git a/cmd/blockchaincmd/stats.go b/cmd/blockchaincmd/stats.go index 7dc4f96f1..f24bba7a5 100644 --- a/cmd/blockchaincmd/stats.go +++ b/cmd/blockchaincmd/stats.go @@ -22,13 +22,6 @@ import ( "github.com/spf13/cobra" ) -var statsSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, -} - // avalanche blockchain stats func newStatsCmd() *cobra.Command { cmd := &cobra.Command{ @@ -38,7 +31,7 @@ func newStatsCmd() *cobra.Command { Args: cobrautils.ExactArgs(1), RunE: stats, } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, statsSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) return cmd } @@ -49,7 +42,7 @@ func stats(_ *cobra.Command, args []string) error { globalNetworkFlags, true, false, - statsSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/blockchaincmd/validators.go b/cmd/blockchaincmd/validators.go index 880a24b57..e7929b33e 100644 --- a/cmd/blockchaincmd/validators.go +++ b/cmd/blockchaincmd/validators.go @@ -19,13 +19,6 @@ import ( "github.com/spf13/cobra" ) -var validatorsSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, -} - // avalanche blockchain validators func newValidatorsCmd() *cobra.Command { cmd := &cobra.Command{ @@ -36,7 +29,7 @@ several statistics about them.`, RunE: printValidators, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, validatorsSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) return cmd } @@ -49,7 +42,7 @@ func printValidators(_ *cobra.Command, args []string) error { globalNetworkFlags, true, false, - validatorsSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, blockchainName, ) if err != nil { diff --git a/cmd/contractcmd/deploy_erc20.go b/cmd/contractcmd/deploy_erc20.go index 704cab7c7..d4a357c06 100644 --- a/cmd/contractcmd/deploy_erc20.go +++ b/cmd/contractcmd/deploy_erc20.go @@ -26,14 +26,7 @@ type DeployERC20Flags struct { rpcEndpoint string } -var ( - deployERC20SupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - } - deployERC20Flags DeployERC20Flags -) +var deployERC20Flags DeployERC20Flags // avalanche contract deploy erc20 func newDeployERC20Cmd() *cobra.Command { @@ -44,7 +37,7 @@ func newDeployERC20Cmd() *cobra.Command { RunE: deployERC20, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &deployERC20Flags.Network, true, deployERC20SupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &deployERC20Flags.Network, true, networkoptions.DefaultSupportedNetworkOptions) deployERC20Flags.PrivateKeyFlags.AddToCmd(cmd, "as contract deployer") // enabling blockchain names, C-Chain and blockchain IDs deployERC20Flags.chainFlags.SetEnabled(true, true, false, false, true) @@ -63,7 +56,7 @@ func deployERC20(_ *cobra.Command, _ []string) error { deployERC20Flags.Network, true, false, - deployERC20SupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/contractcmd/init_validator_manager.go b/cmd/contractcmd/init_validator_manager.go index 7107d3f52..4dcb1c615 100644 --- a/cmd/contractcmd/init_validator_manager.go +++ b/cmd/contractcmd/init_validator_manager.go @@ -45,12 +45,6 @@ type POSManagerSpecFlags struct { } var ( - validatorManagerSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, - } validatorManagerFlags ValidatorManagerFlags initPOSManagerFlags POSManagerSpecFlags ) @@ -64,7 +58,7 @@ func newInitValidatorManagerCmd() *cobra.Command { RunE: initValidatorManager, Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &validatorManagerFlags.Network, true, validatorManagerSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &validatorManagerFlags.Network, true, networkoptions.DefaultSupportedNetworkOptions) validatorManagerFlags.PrivateKeyFlags.AddToCmd(cmd, "as contract deployer") cmd.Flags().StringVar(&validatorManagerFlags.rpcEndpoint, "rpc", "", "deploy the contract into the given rpc endpoint") cmd.Flags().StringSliceVar(&validatorManagerFlags.aggregatorExtraEndpoints, "aggregator-extra-endpoints", nil, "endpoints for extra nodes that are needed in signature aggregation") @@ -93,7 +87,7 @@ func initValidatorManager(_ *cobra.Command, args []string) error { validatorManagerFlags.Network, true, false, - validatorManagerSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/interchaincmd/messengercmd/deploy.go b/cmd/interchaincmd/messengercmd/deploy.go index cb294c631..f958ac7e9 100644 --- a/cmd/interchaincmd/messengercmd/deploy.go +++ b/cmd/interchaincmd/messengercmd/deploy.go @@ -42,14 +42,7 @@ const ( cChainName = "c-chain" ) -var ( - deploySupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - } - deployFlags DeployFlags -) +var deployFlags DeployFlags // avalanche interchain messenger deploy func NewDeployCmd() *cobra.Command { @@ -60,7 +53,7 @@ func NewDeployCmd() *cobra.Command { RunE: deploy, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &deployFlags.Network, true, deploySupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &deployFlags.Network, true, networkoptions.DefaultSupportedNetworkOptions) deployFlags.PrivateKeyFlags.AddToCmd(cmd, "to fund ICM deploy") deployFlags.ChainFlags.SetEnabled(true, true, false, false, true) deployFlags.ChainFlags.AddToCmd(cmd, "deploy ICM into %s") @@ -91,7 +84,7 @@ func CallDeploy(_ []string, flags DeployFlags, network models.Network) error { flags.Network, true, false, - deploySupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/interchaincmd/messengercmd/send_msg.go b/cmd/interchaincmd/messengercmd/send_msg.go index 9539ea6e7..e148649b4 100644 --- a/cmd/interchaincmd/messengercmd/send_msg.go +++ b/cmd/interchaincmd/messengercmd/send_msg.go @@ -29,14 +29,7 @@ type MsgFlags struct { DestRPCEndpoint string } -var ( - msgSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - } - msgFlags MsgFlags -) +var msgFlags MsgFlags // avalanche interchain messenger sendMsg func NewSendMsgCmd() *cobra.Command { @@ -47,7 +40,7 @@ func NewSendMsgCmd() *cobra.Command { RunE: sendMsg, Args: cobrautils.ExactArgs(3), } - networkoptions.AddNetworkFlagsToCmd(cmd, &msgFlags.Network, true, msgSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &msgFlags.Network, true, networkoptions.DefaultSupportedNetworkOptions) msgFlags.PrivateKeyFlags.AddToCmd(cmd, "as message originator and to pay source blockchain fees") cmd.Flags().BoolVar(&msgFlags.HexEncodedMessage, "hex-encoded", false, "given message is hex encoded") cmd.Flags().StringVar(&msgFlags.DestinationAddress, "destination-address", "", "deliver the message to the given contract destination address") @@ -67,7 +60,7 @@ func sendMsg(_ *cobra.Command, args []string) error { msgFlags.Network, true, false, - msgSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/interchaincmd/relayercmd/deploy.go b/cmd/interchaincmd/relayercmd/deploy.go index 6fe7494f7..2b7465814 100644 --- a/cmd/interchaincmd/relayercmd/deploy.go +++ b/cmd/interchaincmd/relayercmd/deploy.go @@ -40,14 +40,7 @@ type DeployFlags struct { AllowPrivateIPs bool } -var ( - deploySupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - } - deployFlags DeployFlags -) +var deployFlags DeployFlags const ( disableDeployToRemotePrompt = true @@ -63,7 +56,7 @@ func newDeployCmd() *cobra.Command { RunE: deploy, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &deployFlags.Network, true, deploySupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &deployFlags.Network, true, networkoptions.NonMainnetSupportedNetworkOptions) cmd.Flags().StringVar(&deployFlags.BinPath, "bin-path", "", "use the given relayer binary") cmd.Flags().StringVar( &deployFlags.Version, @@ -96,7 +89,7 @@ func CallDeploy(_ []string, flags DeployFlags, network models.Network) error { flags.Network, true, false, - deploySupportedNetworkOptions, + networkoptions.NonMainnetSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/interchaincmd/relayercmd/logs.go b/cmd/interchaincmd/relayercmd/logs.go index bf8833dbb..1be5bcb46 100644 --- a/cmd/interchaincmd/relayercmd/logs.go +++ b/cmd/interchaincmd/relayercmd/logs.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/models" "github.com/ava-labs/avalanche-cli/pkg/networkoptions" "github.com/ava-labs/avalanche-cli/pkg/utils" + sdkUtils "github.com/ava-labs/avalanche-cli/sdk/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/jedib0t/go-pretty/v6/table" @@ -131,7 +132,7 @@ func logs(_ *cobra.Command, _ []string) error { keys := maps.Keys(logMap) sort.Strings(keys) for _, k := range keys { - if !utils.Belongs([]string{"logger", "caller", "level", "timestamp", "msg"}, k) { + if !sdkUtils.Belongs([]string{"logger", "caller", "level", "timestamp", "msg"}, k) { logMsg = addAditionalInfo( logMsg, logMap, diff --git a/cmd/interchaincmd/tokentransferrercmd/deploy.go b/cmd/interchaincmd/tokentransferrercmd/deploy.go index b3fca4989..1735e54de 100644 --- a/cmd/interchaincmd/tokentransferrercmd/deploy.go +++ b/cmd/interchaincmd/tokentransferrercmd/deploy.go @@ -52,14 +52,7 @@ type DeployFlags struct { version string } -var ( - deploySupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - } - deployFlags DeployFlags -) +var deployFlags DeployFlags // avalanche interchain tokenTransferrer deploy func NewDeployCmd() *cobra.Command { @@ -70,7 +63,7 @@ func NewDeployCmd() *cobra.Command { RunE: deploy, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &deployFlags.Network, true, deploySupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &deployFlags.Network, true, networkoptions.DefaultSupportedNetworkOptions) deployFlags.homeFlags.chainFlags.SetFlagNames( "home-blockchain", "c-chain-home", @@ -156,7 +149,7 @@ func CallDeploy(_ []string, flags DeployFlags) error { flags.Network, true, false, - deploySupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/keycmd/list.go b/cmd/keycmd/list.go index b7a0d41be..e52608de0 100644 --- a/cmd/keycmd/list.go +++ b/cmd/keycmd/list.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/networkoptions" "github.com/ava-labs/avalanche-cli/pkg/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" + sdkUtils "github.com/ava-labs/avalanche-cli/sdk/utils" "github.com/ava-labs/avalanchego/ids" ledger "github.com/ava-labs/avalanchego/utils/crypto/ledger" "github.com/ava-labs/avalanchego/utils/formatting/address" @@ -21,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/avm" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/coreth/ethclient" + "github.com/ethereum/go-ethereum/common" goethereumethclient "github.com/ethereum/go-ethereum/ethclient" "github.com/liyue201/erc20-go/erc20" @@ -39,25 +41,19 @@ const ( ) var ( - globalNetworkFlags networkoptions.NetworkFlags - listSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Mainnet, - networkoptions.Fuji, - networkoptions.Local, - networkoptions.Devnet, - } - all bool - pchain bool - cchain bool - xchain bool - useNanoAvax bool - useGwei bool - ledgerIndices []uint - keys []string - tokenAddresses []string - subnetToken string - subnets []string - showNativeToken bool + globalNetworkFlags networkoptions.NetworkFlags + all bool + pchain bool + cchain bool + xchain bool + useNanoAvax bool + useGwei bool + ledgerIndices []uint + keys []string + tokenAddresses []string + subnetToken string + subnets []string + showNativeToken bool ) // avalanche blockchain list @@ -69,7 +65,7 @@ func newListCmd() *cobra.Command { keys or for the ledger addresses associated to certain indices.`, RunE: listKeys, } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, listSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().BoolVarP( &all, allFlag, @@ -285,7 +281,7 @@ func listKeys(*cobra.Command, []string) error { globalNetworkFlags, true, false, - listSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { @@ -296,13 +292,13 @@ func listKeys(*cobra.Command, []string) error { if len(subnets) == 0 { subnets = []string{"p", "x", "c"} } - if !utils.Belongs(subnets, "p") { + if !sdkUtils.Belongs(subnets, "p") { pchain = false } - if !utils.Belongs(subnets, "x") { + if !sdkUtils.Belongs(subnets, "x") { xchain = false } - if !utils.Belongs(subnets, "c") { + if !sdkUtils.Belongs(subnets, "c") { cchain = false } queryLedger := len(ledgerIndices) > 0 @@ -311,7 +307,7 @@ func listKeys(*cobra.Command, []string) error { cchain = false xchain = false } - if utils.Belongs(tokenAddresses, "Native") || utils.Belongs(tokenAddresses, "native") { + if sdkUtils.Belongs(tokenAddresses, "Native") || sdkUtils.Belongs(tokenAddresses, "native") { showNativeToken = true } tokenAddresses = utils.RemoveFromSlice(tokenAddresses, "Native") @@ -347,7 +343,7 @@ func getStoredKeysInfo( return nil, err } if len(keys) != 0 { - keyNames = utils.Filter(keyNames, func(keyName string) bool { return utils.Belongs(keys, keyName) }) + keyNames = utils.Filter(keyNames, func(keyName string) bool { return sdkUtils.Belongs(keys, keyName) }) } addrInfos := []addressInfo{} for _, keyName := range keyNames { diff --git a/cmd/keycmd/transfer.go b/cmd/keycmd/transfer.go index a860aef79..783ba4b86 100644 --- a/cmd/keycmd/transfer.go +++ b/cmd/keycmd/transfer.go @@ -46,12 +46,6 @@ const ( ) var ( - transferSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Mainnet, - networkoptions.Fuji, - networkoptions.Devnet, - networkoptions.Local, - } keyName string ledgerIndex uint32 destinationAddrStr string @@ -75,7 +69,7 @@ func newTransferCmd() *cobra.Command { RunE: transferF, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, transferSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVarP( &keyName, keyNameFlag, @@ -164,7 +158,7 @@ func transferF(*cobra.Command, []string) error { globalNetworkFlags, true, false, - transferSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/nodecmd/create.go b/cmd/nodecmd/create.go index e456905fd..894c6c9fe 100644 --- a/cmd/nodecmd/create.go +++ b/cmd/nodecmd/create.go @@ -45,7 +45,6 @@ const ( ) var ( - createSupportedNetworkOptions = []networkoptions.NetworkOption{networkoptions.Fuji, networkoptions.Devnet, networkoptions.Mainnet} globalNetworkFlags networkoptions.NetworkFlags useAWS bool useGCP bool @@ -97,7 +96,7 @@ will apply to all nodes in the cluster`, RunE: createNodes, PersistentPostRun: handlePostRun, } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, createSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.NonLocalSupportedNetworkOptions) cmd.Flags().BoolVar(&useStaticIP, "use-static-ip", true, "attach static Public IP on cloud servers") cmd.Flags().BoolVar(&useAWS, "aws", false, "create node/s in AWS cloud") cmd.Flags().BoolVar(&useGCP, "gcp", false, "create node/s in GCP cloud") @@ -289,7 +288,7 @@ func createNodes(cmd *cobra.Command, args []string) error { globalNetworkFlags, false, true, - createSupportedNetworkOptions, + networkoptions.NonLocalSupportedNetworkOptions, "", ) if err := preCreateChecks(clusterName); err != nil { diff --git a/cmd/nodecmd/local.go b/cmd/nodecmd/local.go index 10d2a05be..57251663f 100644 --- a/cmd/nodecmd/local.go +++ b/cmd/nodecmd/local.go @@ -19,12 +19,6 @@ import ( ) var ( - localStartSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, - } avalanchegoBinaryPath string bootstrapIDs []string @@ -81,7 +75,7 @@ status by running avalanche node status local RunE: localStartNode, PersistentPostRun: handlePostRun, } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, localStartSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().BoolVar(&useLatestAvalanchegoReleaseVersion, "latest-avalanchego-version", false, "install latest avalanchego release version on node/s") cmd.Flags().BoolVar(&useLatestAvalanchegoPreReleaseVersion, "latest-avalanchego-pre-release-version", true, "install latest avalanchego pre-release version on node/s") cmd.Flags().StringVar(&useCustomAvalanchegoVersion, "custom-avalanchego-version", "", "install given avalanchego version on node/s") @@ -190,7 +184,7 @@ func localStartNode(_ *cobra.Command, args []string) error { avaGoVersionSetting, models.Network{}, globalNetworkFlags, - localStartSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, ) } diff --git a/cmd/nodecmd/validate_primary.go b/cmd/nodecmd/validate_primary.go index 3331d9a3b..d80fc2084 100644 --- a/cmd/nodecmd/validate_primary.go +++ b/cmd/nodecmd/validate_primary.go @@ -160,7 +160,7 @@ func PromptWeightPrimaryNetwork(network models.Network) (uint64, error) { case defaultWeight: return defaultStake, nil default: - return app.Prompt.CaptureWeight(txt) + return app.Prompt.CaptureWeight(txt, func(uint64) error { return nil }) } } diff --git a/cmd/primarycmd/add_validator.go b/cmd/primarycmd/add_validator.go index ead3a89ed..ce8e64adc 100644 --- a/cmd/primarycmd/add_validator.go +++ b/cmd/primarycmd/add_validator.go @@ -25,12 +25,7 @@ import ( ) var ( - globalNetworkFlags networkoptions.NetworkFlags - addValidatorSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Fuji, - networkoptions.Mainnet, - networkoptions.Devnet, - } + globalNetworkFlags networkoptions.NetworkFlags keyName string useLedger bool ledgerAddresses []string @@ -60,7 +55,7 @@ in the Primary Network`, RunE: addValidator, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, addValidatorSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.NonLocalSupportedNetworkOptions) cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji only]") cmd.Flags().StringVar(&nodeIDStr, "nodeID", "", "set the NodeID of the validator to add") cmd.Flags().Uint64Var(&weight, "weight", 0, "set the staking weight of the validator to add") @@ -125,7 +120,7 @@ func addValidator(_ *cobra.Command, _ []string) error { globalNetworkFlags, true, false, - addValidatorSupportedNetworkOptions, + networkoptions.NonLocalSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/primarycmd/describe.go b/cmd/primarycmd/describe.go index bf70242dc..5b0395805 100644 --- a/cmd/primarycmd/describe.go +++ b/cmd/primarycmd/describe.go @@ -33,8 +33,6 @@ const art = ` \_____| \_____|_| |_|\__,_|_|_| |_| |_| \__,_|_| \__,_|_| |_| |_|___/ ` -var describeSupportedNetworkOptions = []networkoptions.NetworkOption{networkoptions.Local, networkoptions.Cluster} - // avalanche primary describe func newDescribeCmd() *cobra.Command { cmd := &cobra.Command{ @@ -44,7 +42,7 @@ func newDescribeCmd() *cobra.Command { RunE: describe, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, describeSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.LocalClusterSupportedNetworkOptions) return cmd } @@ -55,7 +53,7 @@ func describe(_ *cobra.Command, _ []string) error { globalNetworkFlags, false, false, - describeSupportedNetworkOptions, + networkoptions.LocalClusterSupportedNetworkOptions, "", ) if err != nil { diff --git a/cmd/validatorcmd/getBalance.go b/cmd/validatorcmd/getBalance.go index 82fb09b0c..eaedbaf5c 100644 --- a/cmd/validatorcmd/getBalance.go +++ b/cmd/validatorcmd/getBalance.go @@ -10,11 +10,10 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/contract" "github.com/ava-labs/avalanche-cli/pkg/models" "github.com/ava-labs/avalanche-cli/pkg/networkoptions" - "github.com/ava-labs/avalanche-cli/pkg/txutils" "github.com/ava-labs/avalanche-cli/pkg/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" - "github.com/ava-labs/avalanche-cli/pkg/validatormanager" - validatorManagerSDK "github.com/ava-labs/avalanche-cli/sdk/validatormanager" + "github.com/ava-labs/avalanche-cli/sdk/validator" + "github.com/ava-labs/avalanche-cli/sdk/validatormanager" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm" @@ -33,13 +32,6 @@ var ( nodeIDStr string ) -var getBalanceSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, -} - func NewGetBalanceCmd() *cobra.Command { cmd := &cobra.Command{ Use: "getBalance", @@ -50,7 +42,7 @@ P-Chain continuous fee`, Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, getBalanceSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVar(&l1, "l1", "", "name of L1") cmd.Flags().StringVar(&validationIDStr, "validation-id", "", "validation ID of the validator") cmd.Flags().StringVar(&nodeIDStr, "node-id", "", "node ID of the validator") @@ -64,7 +56,7 @@ func getBalance(_ *cobra.Command, _ []string) error { globalNetworkFlags, true, false, - getBalanceSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { @@ -82,7 +74,7 @@ func getBalance(_ *cobra.Command, _ []string) error { return fmt.Errorf("the specified node is not a L1 validator") } - balance, err := txutils.GetValidatorPChainBalanceValidationID(network, validationID) + balance, err := validator.GetValidatorBalance(network.SDKNetwork(), validationID) if err != nil { return err } @@ -199,8 +191,8 @@ func getNodeValidationID( if err != nil { return ids.Empty, false, err } - managerAddress := common.HexToAddress(validatorManagerSDK.ProxyContractAddress) - validationID, err = validatormanager.GetRegisteredValidator(rpcURL, managerAddress, nodeID) + managerAddress := common.HexToAddress(validatormanager.ProxyContractAddress) + validationID, err = validator.GetRegisteredValidator(rpcURL, managerAddress, nodeID) if err != nil { return ids.Empty, false, err } diff --git a/cmd/validatorcmd/increaseBalance.go b/cmd/validatorcmd/increaseBalance.go index 67f70b358..d2c337442 100644 --- a/cmd/validatorcmd/increaseBalance.go +++ b/cmd/validatorcmd/increaseBalance.go @@ -5,15 +5,14 @@ package validatorcmd import ( "fmt" + "github.com/ava-labs/avalanche-cli/pkg/cobrautils" "github.com/ava-labs/avalanche-cli/pkg/constants" "github.com/ava-labs/avalanche-cli/pkg/keychain" + "github.com/ava-labs/avalanche-cli/pkg/networkoptions" "github.com/ava-labs/avalanche-cli/pkg/subnet" "github.com/ava-labs/avalanche-cli/pkg/utils" - - "github.com/ava-labs/avalanche-cli/pkg/cobrautils" - "github.com/ava-labs/avalanche-cli/pkg/networkoptions" - "github.com/ava-labs/avalanche-cli/pkg/txutils" "github.com/ava-labs/avalanche-cli/pkg/ux" + "github.com/ava-labs/avalanche-cli/sdk/validator" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/units" "github.com/spf13/cobra" @@ -24,16 +23,9 @@ var ( useLedger bool useEwoq bool ledgerAddresses []string - balanceFlt float64 + balanceAVAX float64 ) -var increaseBalanceSupportedNetworkOptions = []networkoptions.NetworkOption{ - networkoptions.Local, - networkoptions.Devnet, - networkoptions.Fuji, - networkoptions.Mainnet, -} - func NewIncreaseBalanceCmd() *cobra.Command { cmd := &cobra.Command{ Use: "increaseBalance", @@ -43,12 +35,12 @@ func NewIncreaseBalanceCmd() *cobra.Command { Args: cobrautils.ExactArgs(0), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, increaseBalanceSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions) cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji/devnet deploy only]") cmd.Flags().StringVar(&l1, "l1", "", "name of L1 (to increase balance of bootstrap validators only)") cmd.Flags().StringVar(&validationIDStr, "validation-id", "", "validationIDStr of the validator") cmd.Flags().StringVar(&nodeIDStr, "node-id", "", "node ID of the validator") - cmd.Flags().Float64Var(&balanceFlt, "balance", 0, "amount of AVAX to increase validator's balance by") + cmd.Flags().Float64Var(&balanceAVAX, "balance", 0, "amount of AVAX to increase validator's balance by") return cmd } @@ -59,7 +51,7 @@ func increaseBalance(_ *cobra.Command, _ []string) error { globalNetworkFlags, true, false, - getBalanceSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { @@ -94,25 +86,24 @@ func increaseBalance(_ *cobra.Command, _ []string) error { deployer := subnet.NewPublicDeployer(app, kc, network) var balance uint64 - if balanceFlt == 0 { + if balanceAVAX == 0 { availableBalance, err := utils.GetNetworkBalance(kc.Addresses().List(), network.Endpoint) if err != nil { return err } - balance, err = promptValidatorBalance(availableBalance / units.Avax) + balanceAVAX, err = promptValidatorBalanceAVAX(float64(availableBalance) / float64(units.Avax)) if err != nil { return err } - } else { - balance = uint64(balanceFlt * float64(units.Avax)) } + balance = uint64(balanceAVAX * float64(units.Avax)) _, err = deployer.IncreaseValidatorPChainBalance(validationID, balance) if err != nil { return err } deployer.CleanCacheWallet() - balance, err = txutils.GetValidatorPChainBalanceValidationID(network, validationID) + balance, err = validator.GetValidatorBalance(network.SDKNetwork(), validationID) if err != nil { return err } @@ -121,7 +112,7 @@ func increaseBalance(_ *cobra.Command, _ []string) error { return nil } -func promptValidatorBalance(availableBalance uint64) (uint64, error) { +func promptValidatorBalanceAVAX(availableBalance float64) (float64, error) { ux.Logger.PrintToUser("Validator's balance is used to pay for continuous fee to the P-Chain") ux.Logger.PrintToUser("When this Balance reaches 0, the validator will be considered inactive and will no longer participate in validating the L1") txt := "How many AVAX do you want to increase the balance of this validator by?" diff --git a/cmd/validatorcmd/list.go b/cmd/validatorcmd/list.go index 456397aee..b4512383a 100644 --- a/cmd/validatorcmd/list.go +++ b/cmd/validatorcmd/list.go @@ -9,11 +9,10 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/cobrautils" "github.com/ava-labs/avalanche-cli/pkg/contract" "github.com/ava-labs/avalanche-cli/pkg/networkoptions" - "github.com/ava-labs/avalanche-cli/pkg/txutils" "github.com/ava-labs/avalanche-cli/pkg/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" - "github.com/ava-labs/avalanche-cli/pkg/validatormanager" - validatorManagerSDK "github.com/ava-labs/avalanche-cli/sdk/validatormanager" + "github.com/ava-labs/avalanche-cli/sdk/validator" + "github.com/ava-labs/avalanche-cli/sdk/validatormanager" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm" @@ -34,7 +33,7 @@ func NewListCmd() *cobra.Command { Args: cobrautils.ExactArgs(1), } - networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, getBalanceSupportedNetworkOptions) + networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions) return cmd } @@ -54,7 +53,7 @@ func list(_ *cobra.Command, args []string) error { globalNetworkFlags, true, false, - getBalanceSupportedNetworkOptions, + networkoptions.DefaultSupportedNetworkOptions, "", ) if err != nil { @@ -89,7 +88,7 @@ func list(_ *cobra.Command, args []string) error { return err } - managerAddress := common.HexToAddress(validatorManagerSDK.ProxyContractAddress) + managerAddress := common.HexToAddress(validatormanager.ProxyContractAddress) t := ux.DefaultTable( fmt.Sprintf("%s Validators", blockchainName), @@ -105,18 +104,17 @@ func list(_ *cobra.Command, args []string) error { if err != nil { return err } - validator := validators[nodeID] balance := uint64(0) - validationID, err := validatormanager.GetRegisteredValidator(rpcURL, managerAddress, nodeID) + validationID, err := validator.GetRegisteredValidator(rpcURL, managerAddress, nodeID) if err != nil { ux.Logger.RedXToUser("could not get validation ID for node %s due to %s", nodeID, err) } else { - balance, err = txutils.GetValidatorPChainBalanceValidationID(network, validationID) + balance, err = validator.GetValidatorBalance(network.SDKNetwork(), validationID) if err != nil { ux.Logger.RedXToUser("could not get balance for node %s due to %s", nodeID, err) } } - t.AppendRow(table.Row{nodeID, validationID, validator.Weight, float64(balance) / float64(units.Avax)}) + t.AppendRow(table.Row{nodeID, validationID, validators[nodeID].Weight, float64(balance) / float64(units.Avax)}) } fmt.Println(t.Render()) return nil diff --git a/internal/mocks/prompter.go b/internal/mocks/prompter.go index eb42ec239..db75aa642 100644 --- a/internal/mocks/prompter.go +++ b/internal/mocks/prompter.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.46.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -341,7 +341,7 @@ func (_m *Prompter) CaptureID(promptStr string) (ids.ID, error) { } // CaptureIndex provides a mock function with given fields: promptStr, options -func (_m *Prompter) CaptureIndex(promptStr string, options []any) (int, error) { +func (_m *Prompter) CaptureIndex(promptStr string, options []interface{}) (int, error) { ret := _m.Called(promptStr, options) if len(ret) == 0 { @@ -350,16 +350,16 @@ func (_m *Prompter) CaptureIndex(promptStr string, options []any) (int, error) { var r0 int var r1 error - if rf, ok := ret.Get(0).(func(string, []any) (int, error)); ok { + if rf, ok := ret.Get(0).(func(string, []interface{}) (int, error)); ok { return rf(promptStr, options) } - if rf, ok := ret.Get(0).(func(string, []any) int); ok { + if rf, ok := ret.Get(0).(func(string, []interface{}) int); ok { r0 = rf(promptStr, options) } else { r0 = ret.Get(0).(int) } - if rf, ok := ret.Get(1).(func(string, []any) error); ok { + if rf, ok := ret.Get(1).(func(string, []interface{}) error); ok { r1 = rf(promptStr, options) } else { r1 = ret.Error(1) @@ -485,7 +485,7 @@ func (_m *Prompter) CaptureMainnetL1StakingDuration(promptStr string) (time.Dura ret := _m.Called(promptStr) if len(ret) == 0 { - panic("no return value specified for CaptureMainnetDuration") + panic("no return value specified for CaptureMainnetL1StakingDuration") } var r0 time.Duration @@ -989,25 +989,25 @@ func (_m *Prompter) CaptureValidatedString(promptStr string, validator func(stri } // CaptureValidatorBalance provides a mock function with given fields: promptStr, availableBalance, minBalance -func (_m *Prompter) CaptureValidatorBalance(promptStr string, availableBalance uint64, minBalance float64) (uint64, error) { +func (_m *Prompter) CaptureValidatorBalance(promptStr string, availableBalance float64, minBalance float64) (float64, error) { ret := _m.Called(promptStr, availableBalance, minBalance) if len(ret) == 0 { panic("no return value specified for CaptureValidatorBalance") } - var r0 uint64 + var r0 float64 var r1 error - if rf, ok := ret.Get(0).(func(string, uint64, float64) (uint64, error)); ok { + if rf, ok := ret.Get(0).(func(string, float64, float64) (float64, error)); ok { return rf(promptStr, availableBalance, minBalance) } - if rf, ok := ret.Get(0).(func(string, uint64, float64) uint64); ok { + if rf, ok := ret.Get(0).(func(string, float64, float64) float64); ok { r0 = rf(promptStr, availableBalance, minBalance) } else { - r0 = ret.Get(0).(uint64) + r0 = ret.Get(0).(float64) } - if rf, ok := ret.Get(1).(func(string, uint64, float64) error); ok { + if rf, ok := ret.Get(1).(func(string, float64, float64) error); ok { r1 = rf(promptStr, availableBalance, minBalance) } else { r1 = ret.Error(1) @@ -1044,9 +1044,9 @@ func (_m *Prompter) CaptureVersion(promptStr string) (string, error) { return r0, r1 } -// CaptureWeight provides a mock function with given fields: promptStr -func (_m *Prompter) CaptureWeight(promptStr string) (uint64, error) { - ret := _m.Called(promptStr) +// CaptureWeight provides a mock function with given fields: promptStr, validator +func (_m *Prompter) CaptureWeight(promptStr string, validator func(uint64) error) (uint64, error) { + ret := _m.Called(promptStr, validator) if len(ret) == 0 { panic("no return value specified for CaptureWeight") @@ -1054,17 +1054,17 @@ func (_m *Prompter) CaptureWeight(promptStr string) (uint64, error) { var r0 uint64 var r1 error - if rf, ok := ret.Get(0).(func(string) (uint64, error)); ok { - return rf(promptStr) + if rf, ok := ret.Get(0).(func(string, func(uint64) error) (uint64, error)); ok { + return rf(promptStr, validator) } - if rf, ok := ret.Get(0).(func(string) uint64); ok { - r0 = rf(promptStr) + if rf, ok := ret.Get(0).(func(string, func(uint64) error) uint64); ok { + r0 = rf(promptStr, validator) } else { r0 = ret.Get(0).(uint64) } - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(promptStr) + if rf, ok := ret.Get(1).(func(string, func(uint64) error) error); ok { + r1 = rf(promptStr, validator) } else { r1 = ret.Error(1) } diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 9e24a4993..086f32a15 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -336,4 +336,6 @@ const ( // Aggregator DefaultAggregatorLogLevel = "Debug" + + MaxL1TotalWeightChange = 0.2 ) diff --git a/pkg/contract/contract.go b/pkg/contract/contract.go index 5a2608159..56a36009b 100644 --- a/pkg/contract/contract.go +++ b/pkg/contract/contract.go @@ -13,8 +13,8 @@ import ( "strings" "github.com/ava-labs/avalanche-cli/pkg/evm" - "github.com/ava-labs/avalanche-cli/pkg/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" + sdkUtils "github.com/ava-labs/avalanche-cli/sdk/utils" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core/types" @@ -252,7 +252,7 @@ func ParseSpec( } if event { for i := range inputsMaps { - if utils.Belongs(indexedFields, i) { + if sdkUtils.Belongs(indexedFields, i) { inputsMaps[i]["indexed"] = true } } diff --git a/pkg/models/network.go b/pkg/models/network.go index 7d513c21b..a36894c3b 100644 --- a/pkg/models/network.go +++ b/pkg/models/network.go @@ -8,10 +8,10 @@ import ( "os" "strings" + "github.com/ava-labs/avalanche-cli/pkg/constants" "github.com/ava-labs/avalanche-cli/pkg/utils" + sdkNetwork "github.com/ava-labs/avalanche-cli/sdk/network" "github.com/ava-labs/avalanchego/api/info" - - "github.com/ava-labs/avalanche-cli/pkg/constants" "github.com/ava-labs/avalanchego/genesis" avagoconstants "github.com/ava-labs/avalanchego/utils/constants" ) @@ -226,6 +226,20 @@ func (n *Network) BootstrappingContext() (context.Context, context.CancelFunc) { return context.WithTimeout(context.Background(), timeout) } +func (n Network) SDKNetwork() sdkNetwork.Network { + switch n.Kind { + case Fuji: + return sdkNetwork.FujiNetwork() + case Mainnet: + return sdkNetwork.MainnetNetwork() + case Local: + return sdkNetwork.NewNetwork(sdkNetwork.Devnet, n.ID, n.Endpoint) + case Devnet: + return sdkNetwork.NewNetwork(sdkNetwork.Devnet, n.ID, n.Endpoint) + } + return sdkNetwork.UndefinedNetwork +} + // GetNetworkFromCluster gets the network that a cluster is on func GetNetworkFromCluster(clusterConfig ClusterConfig) Network { network := clusterConfig.Network diff --git a/pkg/networkoptions/network_options.go b/pkg/networkoptions/network_options.go index 47e4b7536..80c986168 100644 --- a/pkg/networkoptions/network_options.go +++ b/pkg/networkoptions/network_options.go @@ -31,6 +31,29 @@ const ( Cluster ) +var ( + DefaultSupportedNetworkOptions = []NetworkOption{ + Local, + Devnet, + Fuji, + Mainnet, + } + NonLocalSupportedNetworkOptions = []NetworkOption{ + Devnet, + Fuji, + Mainnet, + } + NonMainnetSupportedNetworkOptions = []NetworkOption{ + Local, + Devnet, + Fuji, + } + LocalClusterSupportedNetworkOptions = []NetworkOption{ + Local, + Cluster, + } +) + func (n NetworkOption) String() string { switch n { case Mainnet: diff --git a/pkg/node/helper.go b/pkg/node/helper.go index 47b96819f..8d749d3c7 100644 --- a/pkg/node/helper.go +++ b/pkg/node/helper.go @@ -28,6 +28,7 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/vm" "github.com/ava-labs/avalanche-cli/sdk/network" "github.com/ava-labs/avalanche-cli/sdk/publicarchive" + sdkUtils "github.com/ava-labs/avalanche-cli/sdk/utils" "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/utils/logging" @@ -196,7 +197,7 @@ func getPublicEndpoints( publicNodes = clusterConfig.Nodes } publicTrackers := utils.Filter(trackers, func(tracker *models.Host) bool { - return utils.Belongs(publicNodes, tracker.GetCloudID()) + return sdkUtils.Belongs(publicNodes, tracker.GetCloudID()) }) endpoints := utils.Map(publicTrackers, func(tracker *models.Host) string { return GetAvalancheGoEndpoint(tracker.IP) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 64bdb78ad..21dd69bf2 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -11,8 +11,6 @@ import ( "strings" "time" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanche-cli/pkg/constants" "github.com/ava-labs/avalanche-cli/pkg/key" "github.com/ava-labs/avalanche-cli/pkg/models" @@ -110,8 +108,8 @@ type Prompter interface { CaptureDate(promptStr string) (time.Time, error) CaptureNodeID(promptStr string) (ids.NodeID, error) CaptureID(promptStr string) (ids.ID, error) - CaptureWeight(promptStr string) (uint64, error) - CaptureValidatorBalance(promptStr string, availableBalance uint64, minBalance float64) (uint64, error) + CaptureWeight(promptStr string, validator func(uint64) error) (uint64, error) + CaptureValidatorBalance(promptStr string, availableBalance float64, minBalance float64) (float64, error) CapturePositiveInt(promptStr string, comparators []Comparator) (int, error) CaptureInt(promptStr string, validator func(int) error) (int, error) CaptureUint8(promptStr string) (uint8, error) @@ -303,12 +301,12 @@ func (*realPrompter) CaptureNodeID(promptStr string) (ids.NodeID, error) { return ids.NodeIDFromString(nodeIDStr) } -// CaptureValidatorBalance captures balance in nanoAVAX +// CaptureValidatorBalance captures balance in AVAX func (*realPrompter) CaptureValidatorBalance( promptStr string, - availableBalance uint64, + availableBalance float64, minBalance float64, -) (uint64, error) { +) (float64, error) { prompt := promptui.Prompt{ Label: promptStr, Validate: validateValidatorBalanceFunc(availableBalance, minBalance), @@ -323,13 +321,22 @@ func (*realPrompter) CaptureValidatorBalance( return 0, err } - return uint64(amountFloat * float64(units.Avax)), nil + return amountFloat, nil } -func (*realPrompter) CaptureWeight(promptStr string) (uint64, error) { +func (*realPrompter) CaptureWeight(promptStr string, validator func(uint64) error) (uint64, error) { prompt := promptui.Prompt{ - Label: promptStr, - Validate: validateWeight, + Label: promptStr, + Validate: func(input string) error { + if err := validateWeight(input); err != nil { + return err + } + val, err := strconv.ParseUint(input, 10, 64) + if err != nil { + return err + } + return validator(val) + }, } amountStr, err := prompt.Run() diff --git a/pkg/prompts/validations.go b/pkg/prompts/validations.go index 28dec477b..144befeee 100644 --- a/pkg/prompts/validations.go +++ b/pkg/prompts/validations.go @@ -149,7 +149,7 @@ func validateWeight(input string) error { return nil } -func validateValidatorBalanceFunc(availableBalance uint64, minBalance float64) func(string) error { +func validateValidatorBalanceFunc(availableBalance float64, minBalance float64) func(string) error { return func(input string) error { val, err := strconv.ParseFloat(input, 64) if err != nil { @@ -159,10 +159,10 @@ func validateValidatorBalanceFunc(availableBalance uint64, minBalance float64) f return fmt.Errorf("entered value has to be greater than 0 AVAX") } if val < minBalance { - return fmt.Errorf("validator balance must be at least %2f AVAX", minBalance) + return fmt.Errorf("validator balance must be at least %.2f AVAX", minBalance) } - if val > float64(availableBalance) { - return fmt.Errorf("current balance of %d is not sufficient for validator balance to be %2f AVAX", availableBalance, val) + if val > availableBalance { + return fmt.Errorf("current balance of %.2f is not sufficient for validator balance to be %.2f AVAX", availableBalance, val) } return nil } diff --git a/pkg/txutils/info.go b/pkg/txutils/info.go index 4cd48b8d1..30bdae4da 100644 --- a/pkg/txutils/info.go +++ b/pkg/txutils/info.go @@ -111,13 +111,3 @@ func GetOwners(network models.Network, subnetID ids.ID) (bool, []string, uint32, } return isPermissioned, controlKeysStrs, threshold, nil } - -func GetValidatorPChainBalanceValidationID(network models.Network, validationID ids.ID) (uint64, error) { - pClient := platformvm.NewClient(network.Endpoint) - ctx := context.Background() - validatorResponse, _, err := pClient.GetL1Validator(ctx, validationID) - if err != nil { - return 0, err - } - return validatorResponse.Balance, nil -} diff --git a/pkg/utils/common.go b/pkg/utils/common.go index a977c8817..5fd2ede67 100644 --- a/pkg/utils/common.go +++ b/pkg/utils/common.go @@ -122,15 +122,6 @@ func Find[T any](input []T, f func(T) bool) *T { return nil } -func Belongs[T comparable](input []T, elem T) bool { - for _, e := range input { - if e == elem { - return true - } - } - return false -} - func RemoveFromSlice[T comparable](input []T, toRemove T) []T { output := make([]T, 0, len(input)) for _, e := range input { diff --git a/pkg/validatormanager/registration.go b/pkg/validatormanager/registration.go index 462d0c3c8..cba4b71fa 100644 --- a/pkg/validatormanager/registration.go +++ b/pkg/validatormanager/registration.go @@ -16,7 +16,8 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" "github.com/ava-labs/avalanche-cli/sdk/interchain" - validatorManagerSDK "github.com/ava-labs/avalanche-cli/sdk/validatormanager" + "github.com/ava-labs/avalanche-cli/sdk/validator" + "github.com/ava-labs/avalanche-cli/sdk/validatormanager" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/platformvm" @@ -84,7 +85,7 @@ func InitializeValidatorRegistrationPoSNative( managerAddress, stakeAmount, "initialize validator registration with stake", - validatorManagerSDK.ErrorSignatureToError, + validatormanager.ErrorSignatureToError, "initializeValidatorRegistration((bytes,bytes,uint64,(uint32,[address]),(uint32,[address])),uint16,uint64)", validatorRegistrationInput, delegationFeeBips, @@ -140,7 +141,7 @@ func InitializeValidatorRegistrationPoA( managerAddress, big.NewInt(0), "initialize validator registration", - validatorManagerSDK.ErrorSignatureToError, + validatormanager.ErrorSignatureToError, "initializeValidatorRegistration((bytes,bytes,uint64,(uint32,[address]),(uint32,[address])),uint64)", validatorRegistrationInput, weight, @@ -171,7 +172,7 @@ func GetSubnetValidatorRegistrationMessage( err error ) if alreadyInitialized { - validationID, err = GetRegisteredValidator( + validationID, err = validator.GetRegisteredValidator( rpcURL, managerAddress, nodeID, @@ -235,27 +236,6 @@ func GetSubnetValidatorRegistrationMessage( return signedMessage, validationID, err } -func GetRegisteredValidator( - rpcURL string, - managerAddress common.Address, - nodeID ids.NodeID, -) (ids.ID, error) { - out, err := contract.CallToMethod( - rpcURL, - managerAddress, - "registeredValidators(bytes)->(bytes32)", - nodeID[:], - ) - if err != nil { - return ids.Empty, err - } - validatorID, b := out[0].([32]byte) - if !b { - return ids.Empty, fmt.Errorf("error at registeredValidators call, expected [32]byte, got %T", out[0]) - } - return validatorID, nil -} - func GetValidatorWeight( rpcURL string, managerAddress common.Address, @@ -342,7 +322,7 @@ func CompleteValidatorRegistration( subnetValidatorRegistrationSignedMessage, big.NewInt(0), "complete validator registration", - validatorManagerSDK.ErrorSignatureToError, + validatormanager.ErrorSignatureToError, "completeValidatorRegistration(uint32)", uint32(0), ) @@ -384,7 +364,7 @@ func InitValidatorRegistration( if err != nil { return nil, ids.Empty, err } - managerAddress := common.HexToAddress(validatorManagerSDK.ProxyContractAddress) + managerAddress := common.HexToAddress(validatormanager.ProxyContractAddress) alreadyInitialized := false if initWithPos { ux.Logger.PrintLineSeparator() @@ -406,14 +386,14 @@ func InitValidatorRegistration( stakeAmount, ) if err != nil { - if !errors.Is(err, validatorManagerSDK.ErrNodeAlreadyRegistered) { + if !errors.Is(err, validatormanager.ErrNodeAlreadyRegistered) { return nil, ids.Empty, evm.TransactionError(tx, err, "failure initializing validator registration") } ux.Logger.PrintToUser(logging.LightBlue.Wrap("The validator registration was already initialized. Proceeding to the next step")) alreadyInitialized = true } } else { - managerAddress = common.HexToAddress(validatorManagerSDK.ProxyContractAddress) + managerAddress = common.HexToAddress(validatormanager.ProxyContractAddress) tx, _, err := InitializeValidatorRegistrationPoA( rpcURL, managerAddress, @@ -426,7 +406,7 @@ func InitValidatorRegistration( weight, ) if err != nil { - if !errors.Is(err, validatorManagerSDK.ErrNodeAlreadyRegistered) { + if !errors.Is(err, validatormanager.ErrNodeAlreadyRegistered) { return nil, ids.Empty, evm.TransactionError(tx, err, "failure initializing validator registration") } ux.Logger.PrintToUser(logging.LightBlue.Wrap("The validator registration was already initialized. Proceeding to the next step")) @@ -434,7 +414,7 @@ func InitValidatorRegistration( } } if initWithPos { - validationID, err := GetRegisteredValidator(rpcURL, managerAddress, nodeID) + validationID, err := validator.GetRegisteredValidator(rpcURL, managerAddress, nodeID) if err != nil { ux.Logger.PrintToUser("Error getting validation ID") return nil, ids.Empty, err @@ -486,7 +466,7 @@ func FinishValidatorRegistration( if err != nil { return err } - managerAddress := common.HexToAddress(validatorManagerSDK.ProxyContractAddress) + managerAddress := common.HexToAddress(validatormanager.ProxyContractAddress) signedMessage, err := GetPChainSubnetValidatorRegistrationWarpMessage( network, rpcURL, @@ -514,7 +494,7 @@ func FinishValidatorRegistration( signedMessage, ) if err != nil { - if !errors.Is(err, validatorManagerSDK.ErrInvalidValidationID) { + if !errors.Is(err, validatormanager.ErrInvalidValidationID) { return evm.TransactionError(tx, err, "failure completing validator registration") } else { return fmt.Errorf("the Validator was already fully registered on the Manager") diff --git a/pkg/validatormanager/removal.go b/pkg/validatormanager/removal.go index 58bde6881..db253cd07 100644 --- a/pkg/validatormanager/removal.go +++ b/pkg/validatormanager/removal.go @@ -15,7 +15,8 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/utils" "github.com/ava-labs/avalanche-cli/pkg/ux" "github.com/ava-labs/avalanche-cli/sdk/interchain" - validatorManagerSDK "github.com/ava-labs/avalanche-cli/sdk/validatormanager" + "github.com/ava-labs/avalanche-cli/sdk/validator" + "github.com/ava-labs/avalanche-cli/sdk/validatormanager" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/logging" @@ -44,7 +45,7 @@ func InitializeValidatorRemoval( managerAddress, big.NewInt(0), "force POS validator removal", - validatorManagerSDK.ErrorSignatureToError, + validatormanager.ErrorSignatureToError, "forceInitializeEndValidation(bytes32,bool,uint32)", validationID, false, // no uptime proof if force @@ -59,7 +60,7 @@ func InitializeValidatorRemoval( uptimeProofSignedMessage, big.NewInt(0), "POS validator removal with uptime proof", - validatorManagerSDK.ErrorSignatureToError, + validatormanager.ErrorSignatureToError, "initializeEndValidation(bytes32,bool,uint32)", validationID, true, // submit uptime proof @@ -73,7 +74,7 @@ func InitializeValidatorRemoval( managerAddress, big.NewInt(0), "POA validator removal initialization", - validatorManagerSDK.ErrorSignatureToError, + validatormanager.ErrorSignatureToError, "initializeEndValidation(bytes32)", validationID, ) @@ -199,8 +200,8 @@ func InitValidatorRemoval( if err != nil { return nil, ids.Empty, err } - managerAddress := common.HexToAddress(validatorManagerSDK.ProxyContractAddress) - validationID, err := GetRegisteredValidator( + managerAddress := common.HexToAddress(validatormanager.ProxyContractAddress) + validationID, err := validator.GetRegisteredValidator( rpcURL, managerAddress, nodeID, @@ -245,7 +246,7 @@ func InitValidatorRemoval( force, ) if err != nil { - if !errors.Is(err, validatorManagerSDK.ErrInvalidValidatorStatus) { + if !errors.Is(err, validatormanager.ErrInvalidValidatorStatus) { return nil, ids.Empty, evm.TransactionError(tx, err, "failure initializing validator removal") } ux.Logger.PrintToUser(logging.LightBlue.Wrap("The validator removal process was already initialized. Proceeding to the next step")) @@ -281,7 +282,7 @@ func CompleteValidatorRemoval( subnetValidatorRegistrationSignedMessage, big.NewInt(0), "complete poa validator removal", - validatorManagerSDK.ErrorSignatureToError, + validatormanager.ErrorSignatureToError, "completeEndValidation(uint32)", uint32(0), ) @@ -298,7 +299,7 @@ func FinishValidatorRemoval( aggregatorAllowPrivatePeers bool, aggregatorLogger logging.Logger, ) error { - managerAddress := common.HexToAddress(validatorManagerSDK.ProxyContractAddress) + managerAddress := common.HexToAddress(validatormanager.ProxyContractAddress) subnetID, err := contract.GetSubnetID( app, network, diff --git a/pkg/vm/allowlist.go b/pkg/vm/allowlist.go index 53851a1bb..fa1404734 100644 --- a/pkg/vm/allowlist.go +++ b/pkg/vm/allowlist.go @@ -10,8 +10,9 @@ import ( "github.com/ava-labs/avalanche-cli/pkg/application" "github.com/ava-labs/avalanche-cli/pkg/utils" - + sdkUtils "github.com/ava-labs/avalanche-cli/sdk/utils" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ethereum/go-ethereum/common" "github.com/olekukonko/tablewriter" "golang.org/x/mod/semver" @@ -58,11 +59,11 @@ func getNewAddresses( } for _, address := range addresses { switch { - case utils.Belongs(allowList.AdminAddresses, address): + case sdkUtils.Belongs(allowList.AdminAddresses, address): fmt.Println(address.Hex() + " is already allowed as admin role") - case utils.Belongs(allowList.ManagerAddresses, address): + case sdkUtils.Belongs(allowList.ManagerAddresses, address): fmt.Println(address.Hex() + " is already allowed as manager role") - case utils.Belongs(allowList.EnabledAddresses, address): + case sdkUtils.Belongs(allowList.EnabledAddresses, address): fmt.Println(address.Hex() + " is already allowed as enabled role") default: newAddresses = append(newAddresses, address) diff --git a/pkg/vm/precompiles.go b/pkg/vm/precompiles.go index fbd79bdab..6360f698a 100644 --- a/pkg/vm/precompiles.go +++ b/pkg/vm/precompiles.go @@ -4,7 +4,7 @@ package vm import ( - "github.com/ava-labs/avalanche-cli/pkg/utils" + sdkUtils "github.com/ava-labs/avalanche-cli/sdk/utils" "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/precompile/allowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/warp" "github.com/ava-labs/subnet-evm/precompile/precompileconfig" + "github.com/ethereum/go-ethereum/common" ) @@ -151,19 +152,19 @@ func addAddressToAllowed( ) allowlist.AllowListConfig { address := common.HexToAddress(addressStr) allowed := false - if utils.Belongs( + if sdkUtils.Belongs( allowListConfig.AdminAddresses, address, ) { allowed = true } - if utils.Belongs( + if sdkUtils.Belongs( allowListConfig.ManagerAddresses, address, ) { allowed = true } - if utils.Belongs( + if sdkUtils.Belongs( allowListConfig.EnabledAddresses, address, ) { diff --git a/sdk/utils/utils.go b/sdk/utils/utils.go index 470705a01..35c4e0542 100644 --- a/sdk/utils/utils.go +++ b/sdk/utils/utils.go @@ -22,6 +22,15 @@ func Unique[T comparable](arr []T) []T { return unique } +func Belongs[T comparable](input []T, elem T) bool { + for _, e := range input { + if e == elem { + return true + } + } + return false +} + func Uint32Sort(arr []uint32) { sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] }) } diff --git a/sdk/validator/validator.go b/sdk/validator/validator.go new file mode 100644 index 000000000..0f98d8587 --- /dev/null +++ b/sdk/validator/validator.go @@ -0,0 +1,92 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. +package validator + +import ( + "fmt" + + "github.com/ava-labs/avalanche-cli/pkg/contract" + "github.com/ava-labs/avalanche-cli/sdk/network" + "github.com/ava-labs/avalanche-cli/sdk/utils" + "github.com/ava-labs/avalanche-cli/sdk/validatormanager" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/platformvm" + "github.com/ava-labs/avalanchego/vms/platformvm/api" + "github.com/ethereum/go-ethereum/common" + "golang.org/x/exp/maps" +) + +func GetTotalWeight(net network.Network, subnetID ids.ID) (uint64, error) { + pClient := platformvm.NewClient(net.Endpoint) + ctx, cancel := utils.GetAPIContext() + defer cancel() + validators, err := pClient.GetValidatorsAt(ctx, subnetID, api.ProposedHeight) + if err != nil { + return 0, err + } + weight := uint64(0) + for _, vdr := range validators { + weight += vdr.Weight + } + return weight, nil +} + +func IsValidator(net network.Network, subnetID ids.ID, nodeID ids.NodeID) (bool, error) { + pClient := platformvm.NewClient(net.Endpoint) + ctx, cancel := utils.GetAPIContext() + defer cancel() + validators, err := pClient.GetValidatorsAt(ctx, subnetID, api.ProposedHeight) + if err != nil { + return false, err + } + nodeIDs := maps.Keys(validators) + return utils.Belongs(nodeIDs, nodeID), nil +} + +func GetValidatorBalance(net network.Network, validationID ids.ID) (uint64, error) { + vdrInfo, err := GetValidatorInfo(net, validationID) + if err != nil { + return 0, err + } + return vdrInfo.Balance, nil +} + +func GetValidatorInfo(net network.Network, validationID ids.ID) (platformvm.L1Validator, error) { + pClient := platformvm.NewClient(net.Endpoint) + ctx, cancel := utils.GetAPIContext() + defer cancel() + vdrInfo, _, err := pClient.GetL1Validator(ctx, validationID) + if err != nil { + return platformvm.L1Validator{}, err + } + return vdrInfo, nil +} + +func GetValidationID(rpcURL string, nodeID ids.NodeID) (ids.ID, error) { + managerAddress := common.HexToAddress(validatormanager.ProxyContractAddress) + return GetRegisteredValidator(rpcURL, managerAddress, nodeID) +} + +func GetRegisteredValidator( + rpcURL string, + managerAddress common.Address, + nodeID ids.NodeID, +) (ids.ID, error) { + out, err := contract.CallToMethod( + rpcURL, + managerAddress, + "registeredValidators(bytes)->(bytes32)", + nodeID[:], + ) + if err != nil { + return ids.Empty, err + } + if len(out) == 0 { + return ids.Empty, fmt.Errorf("error at registeredValidators call, no value returned") + } + validatorID, typeIsOk := out[0].([32]byte) + if !typeIsOk { + return ids.Empty, fmt.Errorf("error at registeredValidators call, expected [32]byte, got %T", out[0]) + } + return validatorID, nil +}