diff --git a/client/cmd/flags.go b/client/cmd/flags.go index 17ac1387..eb9aa263 100644 --- a/client/cmd/flags.go +++ b/client/cmd/flags.go @@ -147,6 +147,10 @@ func bindRollbackFlags(cmd *cobra.Command, cfg *config.Config) { func bindValidatorUnjailFlags(cmd *cobra.Command, cfg *unjailConfig) { bindValidatorBaseFlags(cmd, &cfg.baseConfig) +} + +func bindValidatorUnjailOnBehalfFlags(cmd *cobra.Command, cfg *unjailConfig) { + bindValidatorBaseFlags(cmd, &cfg.baseConfig) cmd.Flags().StringVar(&cfg.ValidatorPubKey, "validator-pubkey", "", "Validator's hex-encoded compressed 33-byte secp256k1 public key") } @@ -229,6 +233,10 @@ func validateKeyConvertFlags(cmd *cobra.Command) error { } func validateValidatorUnjailFlags(cmd *cobra.Command) error { + return validateFlags(cmd, []string{}) +} + +func validateValidatorUnjailOnBehalfFlags(cmd *cobra.Command) error { return validateFlags(cmd, []string{"validator-pubkey"}) } diff --git a/client/cmd/validator.go b/client/cmd/validator.go index 1d550a28..fe580736 100644 --- a/client/cmd/validator.go +++ b/client/cmd/validator.go @@ -147,6 +147,7 @@ func newValidatorCmds() *cobra.Command { newValidatorRemoveOperatorCmd(), newValidatorSetWithdrawalAddressCmd(), newValidatorUnjailCmd(), + newValidatorUnjailOnBehalfCmd(), ) return cmd @@ -376,6 +377,27 @@ func newValidatorUnjailCmd() *cobra.Command { return cmd } +func newValidatorUnjailOnBehalfCmd() *cobra.Command { + var cfg unjailConfig + + cmd := &cobra.Command{ + Use: "unjail-on-behalf", + Short: "Unjail the validator on behalf of a validator", + Args: cobra.NoArgs, + PreRunE: func(_ *cobra.Command, _ []string) error { + return initializeBaseConfig(&cfg.baseConfig) + }, + RunE: runValidatorCommand( + validateValidatorUnjailOnBehalfFlags, + func(ctx context.Context) error { return unjailOnBehalf(ctx, cfg) }, + ), + } + + bindValidatorUnjailOnBehalfFlags(cmd, &cfg) + + return cmd +} + func runValidatorCommand( validate func(cmd *cobra.Command) error, execute func(ctx context.Context) error, @@ -710,6 +732,35 @@ func unstakeOnBehalf(ctx context.Context, cfg unstakeConfig) error { } func unjail(ctx context.Context, cfg unjailConfig) error { + uncompressedValidatorPubKeyBytes, err := uncompressPrivateKey(cfg.PrivateKey) + if err != nil { + return errors.Wrap(err, "failed to get uncompressed pub key from private key") + } + + result, err := prepareAndReadContract(ctx, &cfg.baseConfig, "fee") + if err != nil { + return err + } + + var unjailFee *big.Int + err = cfg.ABI.UnpackIntoInterface(&unjailFee, "fee", result) + if err != nil { + return errors.Wrap(err, "failed to unpack unjailFee") + } + + fmt.Printf("Unjail fee: %s\n", unjailFee.String()) + + _, err = prepareAndExecuteTransaction(ctx, &cfg.baseConfig, "unjailOnBehalf", unjailFee, uncompressedValidatorPubKeyBytes, []byte{}) + if err != nil { + return err + } + + fmt.Println("Validator successfully unjailed on behalf of validator!") + + return nil +} + +func unjailOnBehalf(ctx context.Context, cfg unjailConfig) error { validatorPubKeyBytes, err := hex.DecodeString(cfg.ValidatorPubKey) if err != nil { return errors.Wrap(err, "failed to decode hex-encoded validator public key") @@ -738,7 +789,7 @@ func unjail(ctx context.Context, cfg unjailConfig) error { return err } - fmt.Println("Validator successfully unjailed!") + fmt.Println("Validator successfully unjailed on behalf of validator!") return nil }