Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

to remove validators decide sov/nonsov based on nodeID #2622

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 30 additions & 66 deletions cmd/blockchaincmd/remove_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ import (
"strings"

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

"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ethereum/go-ethereum/common"

"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
"github.com/ava-labs/avalanche-cli/pkg/constants"
"github.com/ava-labs/avalanche-cli/pkg/contract"
Expand All @@ -27,11 +22,14 @@ import (
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanche-cli/pkg/validatormanager"
sdkutils "github.com/ava-labs/avalanche-cli/sdk/utils"
validatorsdk "github.com/ava-labs/avalanche-cli/sdk/validator"
validatormanagerSDK "github.com/ava-labs/avalanche-cli/sdk/validatormanager"
"github.com/ava-labs/avalanchego/genesis"
"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/vms/platformvm/warp"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
"github.com/ethereum/go-ethereum/common"

"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -99,6 +97,7 @@ func removeValidator(_ *cobra.Command, args []string) error {
if network.ClusterName != "" {
network = models.ConvertClusterToNetwork(network)
}

// TODO: will estimate fee in subsecuent PR
fee := uint64(0)
kc, err := keychain.GetKeychainFromCmdLineFlags(
Expand All @@ -116,19 +115,10 @@ func removeValidator(_ *cobra.Command, args []string) error {
}
network.HandlePublicNetworkSimulation()

if !sc.Sovereign {
if outputTxPath != "" {
return errors.New("--output-tx-path flag cannot be used for non-SOV (Subnet-Only Validators) blockchains")
}

if len(subnetAuthKeys) > 0 {
return errors.New("--subnetAuthKeys flag cannot be used for non-SOV (Subnet-Only Validators) blockchains")
}
}
if outputTxPath != "" {
if _, err := os.Stat(outputTxPath); err == nil {
return fmt.Errorf("outputTxPath %q already exists", outputTxPath)
}
scNetwork := sc.Networks[network.Name()]
subnetID := scNetwork.SubnetID
if subnetID == ids.Empty {
return errNoSubnetID
}

var nodeID ids.NodeID
Expand All @@ -153,19 +143,31 @@ func removeValidator(_ *cobra.Command, args []string) error {
}
}

if network.Kind == models.Local && !sc.Sovereign {
return removeFromLocalNonSOV(blockchainName, nodeID)
validatorKind, err := validatorsdk.IsSovereignValidator(network.SDKNetwork(), subnetID, nodeID)
if err != nil {
return err
}
if validatorKind == validatorsdk.NonValidator {
return fmt.Errorf("node %s is not a validator of subnet %s on %s", nodeID, subnetID, network.Name())
}

scNetwork := sc.Networks[network.Name()]
subnetID := scNetwork.SubnetID
if subnetID == ids.Empty {
return errNoSubnetID
if validatorKind == validatorsdk.SovereignValidator {
if outputTxPath != "" {
return errors.New("--output-tx-path flag cannot be used for non-SOV (Subnet-Only Validators) blockchains")
}

if len(subnetAuthKeys) > 0 {
return errors.New("--subnetAuthKeys flag cannot be used for non-SOV (Subnet-Only Validators) blockchains")
}
}
if outputTxPath != "" {
if _, err := os.Stat(outputTxPath); err == nil {
return fmt.Errorf("outputTxPath %q already exists", outputTxPath)
}
}

deployer := subnet.NewPublicDeployer(app, kc, network)
// check that this guy actually is a validator on the subnet
if !sc.Sovereign {
if validatorKind == validatorsdk.NonSovereignValidator {
isValidator, err := subnet.IsSubnetValidator(subnetID, nodeID, network)
if err != nil {
// just warn the user, don't fail
Expand Down Expand Up @@ -433,41 +435,3 @@ func removeValidatorNonSOV(deployer *subnet.PublicDeployer, network models.Netwo
}
return err
}

func removeFromLocalNonSOV(
blockchainName string,
nodeID ids.NodeID,
) error {
sc, err := app.LoadSidecar(blockchainName)
if err != nil {
return err
}

subnetID := sc.Networks[models.Local.String()].SubnetID
if subnetID == ids.Empty {
return errNoSubnetID
}

// Get NodeIDs of all validators on the subnet
validators, err := subnet.GetSubnetValidators(subnetID)
if err != nil {
return err
}

// construct list of validators to choose from
validatorList := make([]string, len(validators))
for i, v := range validators {
validatorList[i] = v.NodeID.String()
}

testKey := genesis.EWOQKey
keyChain := secp256k1fx.NewKeychain(testKey)
_, err = subnet.IssueRemoveSubnetValidatorTx(keyChain, subnetID, nodeID)
if err != nil {
return err
}

ux.Logger.PrintToUser("Validator removed")

return nil
}
32 changes: 32 additions & 0 deletions sdk/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ import (
"golang.org/x/exp/maps"
)

type ValidatorKind int64

const (
UndefinedValidatorKind ValidatorKind = iota
NonValidator
SovereignValidator
NonSovereignValidator
)

func GetTotalWeight(net network.Network, subnetID ids.ID) (uint64, error) {
pClient := platformvm.NewClient(net.Endpoint)
ctx, cancel := utils.GetAPIContext()
Expand Down Expand Up @@ -89,3 +98,26 @@ func GetRegisteredValidator(
}
return validatorID, nil
}

func IsSovereignValidator(
network network.Network,
subnetID ids.ID,
nodeID ids.NodeID,
) (ValidatorKind, error) {
pClient := platformvm.NewClient(network.Endpoint)
ctx, cancel := utils.GetAPIContext()
defer cancel()
vs, err := pClient.GetCurrentValidators(ctx, subnetID, nil)
if err != nil {
return UndefinedValidatorKind, err
}
for _, v := range vs {
if v.NodeID == nodeID {
if v.TxID == ids.Empty {
return SovereignValidator, nil
}
return NonSovereignValidator, nil
}
}
return NonValidator, nil
}
Loading