From 8dc045714df6b566d638bfd4099ce1df84a712db Mon Sep 17 00:00:00 2001 From: Goran Rojovic Date: Mon, 24 Apr 2023 11:47:46 +0200 Subject: [PATCH] Change validator info command --- command/polybft/polybft_command.go | 3 +- command/rootchain/helper/metadata.go | 47 ++++++++++++++++++- command/rootchain/validators/params.go | 44 +++++++++++++++++ .../validators/validator_info.go | 23 ++++++--- command/sidechain/helper.go | 1 + command/sidechain/validators/params.go | 47 ------------------- consensus/polybft/system_state.go | 4 ++ 7 files changed, 113 insertions(+), 56 deletions(-) create mode 100644 command/rootchain/validators/params.go rename command/{sidechain => rootchain}/validators/validator_info.go (73%) delete mode 100644 command/sidechain/validators/params.go diff --git a/command/polybft/polybft_command.go b/command/polybft/polybft_command.go index 9f31db8b25..1496222775 100644 --- a/command/polybft/polybft_command.go +++ b/command/polybft/polybft_command.go @@ -4,9 +4,9 @@ import ( "github.com/0xPolygon/polygon-edge/command/rootchain/registration" "github.com/0xPolygon/polygon-edge/command/rootchain/staking" "github.com/0xPolygon/polygon-edge/command/rootchain/supernet" + "github.com/0xPolygon/polygon-edge/command/rootchain/validators" "github.com/0xPolygon/polygon-edge/command/rootchain/whitelist" "github.com/0xPolygon/polygon-edge/command/sidechain/unstaking" - "github.com/0xPolygon/polygon-edge/command/sidechain/validators" "github.com/0xPolygon/polygon-edge/command/sidechain/withdraw" "github.com/spf13/cobra" @@ -21,6 +21,7 @@ func GetCommand() *cobra.Command { polybftCmd.AddCommand( unstaking.GetCommand(), withdraw.GetCommand(), + // rootchain (supernet manager) command that queries validator info validators.GetCommand(), // rootchain (supernet manager) whitelist validator whitelist.GetCommand(), diff --git a/command/rootchain/helper/metadata.go b/command/rootchain/helper/metadata.go index cd99821893..d4d8a823fe 100644 --- a/command/rootchain/helper/metadata.go +++ b/command/rootchain/helper/metadata.go @@ -2,12 +2,17 @@ package helper import ( "context" - "encoding/hex" "errors" "fmt" + "math/big" "github.com/0xPolygon/polygon-edge/command/polybftsecrets" + "github.com/0xPolygon/polygon-edge/consensus/polybft" + "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" polybftWallet "github.com/0xPolygon/polygon-edge/consensus/polybft/wallet" + "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/helper/hex" + "github.com/0xPolygon/polygon-edge/txrelayer" dockertypes "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/umbracle/ethgo" @@ -109,3 +114,43 @@ func GetECDSAKey(privateKey, accountDir, accountConfig string) (ethgo.Key, error return polybftWallet.GetEcdsaFromSecret(secretsManager) } + +// GetValidatorInfo queries SupernetManager smart contract on root +// and retrieves validator info for given address +func GetValidatorInfo(validatorAddr, supernetManagerAddr ethgo.Address, + txRelayer txrelayer.TxRelayer) (*polybft.ValidatorInfo, error) { + getValidatorMethod := contractsapi.CustomSupernetManager.Abi.GetMethod("validators") + + encode, err := getValidatorMethod.Encode([]interface{}{validatorAddr}) + if err != nil { + return nil, err + } + + response, err := txRelayer.Call(ethgo.Address(contracts.SystemCaller), + supernetManagerAddr, encode) + if err != nil { + return nil, err + } + + byteResponse, err := hex.DecodeHex(response) + if err != nil { + return nil, fmt.Errorf("unable to decode hex response, %w", err) + } + + decoded, err := getValidatorMethod.Outputs.Decode(byteResponse) + if err != nil { + return nil, err + } + + decodedOutputsMap, ok := decoded.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("could not convert decoded outputs to map") + } + + return &polybft.ValidatorInfo{ + Address: validatorAddr.Address(), + Stake: decodedOutputsMap["stake"].(*big.Int), //nolint:forcetypeassert + Active: decodedOutputsMap["isActive"].(bool), //nolint:forcetypeassert + Whitelisted: decodedOutputsMap["isWhitelisted"].(bool), //nolint:forcetypeassert + }, nil +} diff --git a/command/rootchain/validators/params.go b/command/rootchain/validators/params.go new file mode 100644 index 0000000000..684ee91ccb --- /dev/null +++ b/command/rootchain/validators/params.go @@ -0,0 +1,44 @@ +package validators + +import ( + "bytes" + "fmt" + + "github.com/0xPolygon/polygon-edge/command/helper" + sidechainHelper "github.com/0xPolygon/polygon-edge/command/sidechain" +) + +type validatorInfoParams struct { + accountDir string + accountConfig string + jsonRPC string + supernetManagerAddress string +} + +func (v *validatorInfoParams) validateFlags() error { + return sidechainHelper.ValidateSecretFlags(v.accountDir, v.accountConfig) +} + +type validatorsInfoResult struct { + address string + stake uint64 + active bool + whitelisted bool +} + +func (vr validatorsInfoResult) GetOutput() string { + var buffer bytes.Buffer + + buffer.WriteString("\n[VALIDATOR INFO]\n") + + vals := make([]string, 4) + vals[0] = fmt.Sprintf("Validator Address|%s", vr.address) + vals[1] = fmt.Sprintf("Stake|%v", vr.stake) + vals[2] = fmt.Sprintf("Is Whitelisted|%v", vr.whitelisted) + vals[3] = fmt.Sprintf("Is Active|%v", vr.active) + + buffer.WriteString(helper.FormatKV(vals)) + buffer.WriteString("\n") + + return buffer.String() +} diff --git a/command/sidechain/validators/validator_info.go b/command/rootchain/validators/validator_info.go similarity index 73% rename from command/sidechain/validators/validator_info.go rename to command/rootchain/validators/validator_info.go index d6af0a050a..d4c66bec5d 100644 --- a/command/sidechain/validators/validator_info.go +++ b/command/rootchain/validators/validator_info.go @@ -6,9 +6,12 @@ import ( "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/helper" "github.com/0xPolygon/polygon-edge/command/polybftsecrets" + rootHelper "github.com/0xPolygon/polygon-edge/command/rootchain/helper" sidechainHelper "github.com/0xPolygon/polygon-edge/command/sidechain" "github.com/0xPolygon/polygon-edge/txrelayer" + "github.com/0xPolygon/polygon-edge/types" "github.com/spf13/cobra" + "github.com/umbracle/ethgo" ) var ( @@ -44,6 +47,13 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.AccountConfigFlagDesc, ) + cmd.Flags().StringVar( + ¶ms.supernetManagerAddress, + rootHelper.SupernetManagerFlag, + "", + rootHelper.SupernetManagerFlagDesc, + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) } @@ -68,19 +78,18 @@ func runCommand(cmd *cobra.Command, _ []string) error { } validatorAddr := validatorAccount.Ecdsa.Address() + supernetManagerAddr := ethgo.Address(types.StringToAddress(params.supernetManagerAddress)) - validatorInfo, err := sidechainHelper.GetValidatorInfo(validatorAddr, txRelayer) + validatorInfo, err := rootHelper.GetValidatorInfo(validatorAddr, supernetManagerAddr, txRelayer) if err != nil { return fmt.Errorf("failed to get validator info for %s: %w", validatorAddr, err) } outputter.WriteCommandResult(&validatorsInfoResult{ - address: validatorInfo.Address.String(), - stake: validatorInfo.Stake.Uint64(), - totalStake: validatorInfo.TotalStake.Uint64(), - commission: validatorInfo.Commission.Uint64(), - withdrawableRewards: validatorInfo.WithdrawableRewards.Uint64(), - active: validatorInfo.Active, + address: validatorInfo.Address.String(), + stake: validatorInfo.Stake.Uint64(), + active: validatorInfo.Active, + whitelisted: validatorInfo.Whitelisted, }) return nil diff --git a/command/sidechain/helper.go b/command/sidechain/helper.go index 5c2c717140..107d47286f 100644 --- a/command/sidechain/helper.go +++ b/command/sidechain/helper.go @@ -61,6 +61,7 @@ func GetAccountFromDir(accountDir string) (*wallet.Account, error) { } // GetValidatorInfo queries ChildValidatorSet smart contract and retrieves validator info for given address +// @TODO - depricate this function once we change e2e tests func GetValidatorInfo(validatorAddr ethgo.Address, txRelayer txrelayer.TxRelayer) (*polybft.ValidatorInfo, error) { getValidatorMethod := contractsapi.ChildValidatorSet.Abi.GetMethod("getValidator") diff --git a/command/sidechain/validators/params.go b/command/sidechain/validators/params.go deleted file mode 100644 index a69f077d77..0000000000 --- a/command/sidechain/validators/params.go +++ /dev/null @@ -1,47 +0,0 @@ -package validators - -import ( - "bytes" - "fmt" - - "github.com/0xPolygon/polygon-edge/command/helper" - sidechainHelper "github.com/0xPolygon/polygon-edge/command/sidechain" -) - -type validatorInfoParams struct { - accountDir string - accountConfig string - jsonRPC string -} - -func (v *validatorInfoParams) validateFlags() error { - return sidechainHelper.ValidateSecretFlags(v.accountDir, v.accountConfig) -} - -type validatorsInfoResult struct { - address string - stake uint64 - totalStake uint64 - commission uint64 - withdrawableRewards uint64 - active bool -} - -func (vr validatorsInfoResult) GetOutput() string { - var buffer bytes.Buffer - - buffer.WriteString("\n[VALIDATOR INFO]\n") - - vals := make([]string, 0, 5) - vals = append(vals, fmt.Sprintf("Validator Address|%s", vr.address)) - vals = append(vals, fmt.Sprintf("Self Stake|%v", vr.stake)) - vals = append(vals, fmt.Sprintf("Total Stake|%v", vr.totalStake)) - vals = append(vals, fmt.Sprintf("Withdrawable Rewards|%v", vr.withdrawableRewards)) - vals = append(vals, fmt.Sprintf("Commission|%v", vr.commission)) - vals = append(vals, fmt.Sprintf("Is Active|%v", vr.active)) - - buffer.WriteString(helper.FormatKV(vals)) - buffer.WriteString("\n") - - return buffer.String() -} diff --git a/consensus/polybft/system_state.go b/consensus/polybft/system_state.go index f4dfbee5e8..d621f9609f 100644 --- a/consensus/polybft/system_state.go +++ b/consensus/polybft/system_state.go @@ -14,6 +14,9 @@ import ( // ValidatorInfo is data transfer object which holds validator information, // provided by smart contract +// TODO - @goran-ethernal deprecate this struct once we change e2e tests +// we will instead use the contractsapi generated stub once we remove old +// ChildValidatorSet contract and its stubs type ValidatorInfo struct { Address ethgo.Address Stake *big.Int @@ -21,6 +24,7 @@ type ValidatorInfo struct { Commission *big.Int WithdrawableRewards *big.Int Active bool + Whitelisted bool } // SystemState is an interface to interact with the consensus system contracts in the chain