Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
parent
4fac43125a
commit
0f419f36d8
@ -23,6 +23,12 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
AddressStringScalarType = "cosmos.AddressString"
|
||||
ValidatorAddressStringScalarType = "cosmos.ValidatorAddressString"
|
||||
ConsensusAddressStringScalarType = "cosmos.ConsensusAddressString"
|
||||
)
|
||||
|
||||
// Builder manages options for building pflag flags for protobuf messages.
|
||||
type Builder struct {
|
||||
// TypeResolver specifies how protobuf types will be resolved. If it is
|
||||
@ -61,9 +67,9 @@ func (b *Builder) init() {
|
||||
|
||||
if b.scalarFlagTypes == nil {
|
||||
b.scalarFlagTypes = map[string]Type{}
|
||||
b.scalarFlagTypes["cosmos.AddressString"] = addressStringType{}
|
||||
b.scalarFlagTypes["cosmos.ValidatorAddressString"] = validatorAddressStringType{}
|
||||
b.scalarFlagTypes["cosmos.ConsensusAddressString"] = consensusAddressStringType{}
|
||||
b.scalarFlagTypes[AddressStringScalarType] = addressStringType{}
|
||||
b.scalarFlagTypes[ValidatorAddressStringScalarType] = validatorAddressStringType{}
|
||||
b.scalarFlagTypes[ConsensusAddressStringScalarType] = consensusAddressStringType{}
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,10 +393,10 @@ func (b *Builder) resolveFlagType(field protoreflect.FieldDescriptor) Type {
|
||||
}
|
||||
|
||||
func (b *Builder) resolveFlagTypeBasic(field protoreflect.FieldDescriptor) Type {
|
||||
scalar := proto.GetExtension(field.Options(), cosmos_proto.E_Scalar)
|
||||
if scalar != nil {
|
||||
scalar, ok := GetScalarType(field)
|
||||
if ok {
|
||||
b.init()
|
||||
if typ, ok := b.scalarFlagTypes[scalar.(string)]; ok {
|
||||
if typ, ok := b.scalarFlagTypes[scalar]; ok {
|
||||
return typ
|
||||
}
|
||||
}
|
||||
@ -413,6 +419,13 @@ func (b *Builder) resolveFlagTypeBasic(field protoreflect.FieldDescriptor) Type
|
||||
}
|
||||
}
|
||||
|
||||
// GetScalarType gets scalar type of a field.
|
||||
func GetScalarType(field protoreflect.FieldDescriptor) (string, bool) {
|
||||
scalar := proto.GetExtension(field.Options(), cosmos_proto.E_Scalar)
|
||||
scalarStr, ok := scalar.(string)
|
||||
return scalarStr, ok
|
||||
}
|
||||
|
||||
// GetSignerFieldName gets signer field name of a message.
|
||||
// AutoCLI supports only one signer field per message.
|
||||
func GetSignerFieldName(descriptor protoreflect.MessageDescriptor) string {
|
||||
|
||||
@ -131,8 +131,21 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
|
||||
// set signer to signer field if empty
|
||||
fd := input.Descriptor().Fields().ByName(protoreflect.Name(flag.GetSignerFieldName(input.Descriptor())))
|
||||
if addr := input.Get(fd).String(); addr == "" {
|
||||
addressCodec := b.Builder.AddressCodec
|
||||
|
||||
scalarType, ok := flag.GetScalarType(fd)
|
||||
if ok {
|
||||
// override address codec if validator or consensus address
|
||||
switch scalarType {
|
||||
case flag.ValidatorAddressStringScalarType:
|
||||
addressCodec = b.Builder.ValidatorAddressCodec
|
||||
case flag.ConsensusAddressStringScalarType:
|
||||
addressCodec = b.Builder.ConsensusAddressCodec
|
||||
}
|
||||
}
|
||||
|
||||
signerFromFlag := clientCtx.GetFromAddress()
|
||||
signer, err := b.AddressCodec.BytesToString(signerFromFlag.Bytes())
|
||||
signer, err := addressCodec.BytesToString(signerFromFlag.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set signer on message, got %v: %w", signerFromFlag, err)
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ go 1.21
|
||||
|
||||
require (
|
||||
cosmossdk.io/api v0.7.1
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009114728-5259373edec8
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009141709-5e209c3c0fce
|
||||
cosmossdk.io/collections v0.4.0 // indirect
|
||||
cosmossdk.io/core v0.11.0
|
||||
cosmossdk.io/depinject v1.0.0-alpha.4
|
||||
|
||||
@ -189,8 +189,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
|
||||
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
|
||||
cosmossdk.io/api v0.7.1 h1:PNQ1xN8+/0hj/sSD0ANqjkgfXFys+bZ5L8Hg7uzoUTU=
|
||||
cosmossdk.io/api v0.7.1/go.mod h1:ure9edhcROIHsngavM6mBLilMGFnfjhV/AaYhEMUkdo=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009114728-5259373edec8 h1:IEBOxiA/KO2MeKEOwr1AUczynjWmWPooZ3U/naf6kTE=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009114728-5259373edec8/go.mod h1:VqOuMtieftq2OaX7WhRXjG0mhFih4qzw5JT8fyNlVuE=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009141709-5e209c3c0fce h1:k3Yk/99Tg4IY0KictwPBYwZSuK6uyqrw6YoJStD3C9o=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009141709-5e209c3c0fce/go.mod h1:VqOuMtieftq2OaX7WhRXjG0mhFih4qzw5JT8fyNlVuE=
|
||||
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
|
||||
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
|
||||
cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo=
|
||||
|
||||
@ -37,7 +37,7 @@ require (
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
cloud.google.com/go/storage v1.30.1 // indirect
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009114728-5259373edec8 // indirect
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009141709-5e209c3c0fce // indirect
|
||||
cosmossdk.io/collections v0.4.0 // indirect
|
||||
cosmossdk.io/x/circuit v0.0.0-20231006095526-33390754f9fe // indirect
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
|
||||
@ -189,8 +189,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
|
||||
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
|
||||
cosmossdk.io/api v0.7.1 h1:PNQ1xN8+/0hj/sSD0ANqjkgfXFys+bZ5L8Hg7uzoUTU=
|
||||
cosmossdk.io/api v0.7.1/go.mod h1:ure9edhcROIHsngavM6mBLilMGFnfjhV/AaYhEMUkdo=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009114728-5259373edec8 h1:IEBOxiA/KO2MeKEOwr1AUczynjWmWPooZ3U/naf6kTE=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009114728-5259373edec8/go.mod h1:VqOuMtieftq2OaX7WhRXjG0mhFih4qzw5JT8fyNlVuE=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009141709-5e209c3c0fce h1:k3Yk/99Tg4IY0KictwPBYwZSuK6uyqrw6YoJStD3C9o=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231009141709-5e209c3c0fce/go.mod h1:VqOuMtieftq2OaX7WhRXjG0mhFih4qzw5JT8fyNlVuE=
|
||||
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
|
||||
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
|
||||
cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo=
|
||||
|
||||
@ -36,5 +36,20 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
|
||||
},
|
||||
},
|
||||
},
|
||||
Tx: &autocliv1.ServiceCommandDescriptor{
|
||||
Service: slashingv1beta.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Unjail",
|
||||
Use: "unjail",
|
||||
Short: "Unjail a jailed validator",
|
||||
Example: fmt.Sprintf("%s tx slashing unjail --from [validator]", version.AppName),
|
||||
},
|
||||
{
|
||||
RpcMethod: "UpdateParams",
|
||||
Skip: true, // skipped because authority gated
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
package cli
|
||||
|
||||
const (
|
||||
FlagAddressValidator = "validator"
|
||||
)
|
||||
@ -1,58 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
// NewTxCmd returns a root CLI command handler for all x/slashing transaction commands.
|
||||
func NewTxCmd(ac address.Codec) *cobra.Command {
|
||||
slashingTxCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Slashing transaction subcommands",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
slashingTxCmd.AddCommand(NewUnjailTxCmd(ac))
|
||||
return slashingTxCmd
|
||||
}
|
||||
|
||||
// NewUnjailTxCmd returns a CLI command handler for creating a MsgUnjail transaction.
|
||||
func NewUnjailTxCmd(valAc address.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "unjail",
|
||||
Args: cobra.NoArgs,
|
||||
Short: "unjail validator previously jailed for downtime",
|
||||
Long: `unjail a jailed validator:
|
||||
|
||||
$ <appd> tx slashing unjail --from mykey
|
||||
`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
valAddr, err := valAc.BytesToString(clientCtx.GetFromAddress())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgUnjail(valAddr)
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/codec/address"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
|
||||
)
|
||||
|
||||
type CLITestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
kr keyring.Keyring
|
||||
baseCtx client.Context
|
||||
clientCtx client.Context
|
||||
encCfg testutilmod.TestEncodingConfig
|
||||
|
||||
pub types.PubKey
|
||||
addr sdk.AccAddress
|
||||
}
|
||||
|
||||
func TestCLITestSuite(t *testing.T) {
|
||||
suite.Run(t, new(CLITestSuite))
|
||||
}
|
||||
|
||||
func (s *CLITestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
s.encCfg = testutilmod.MakeTestEncodingConfig(slashing.AppModuleBasic{})
|
||||
s.kr = keyring.NewInMemory(s.encCfg.Codec)
|
||||
s.baseCtx = client.Context{}.
|
||||
WithKeyring(s.kr).
|
||||
WithTxConfig(s.encCfg.TxConfig).
|
||||
WithCodec(s.encCfg.Codec).
|
||||
WithClient(clitestutil.MockCometRPC{Client: rpcclientmock.Client{}}).
|
||||
WithAccountRetriever(client.MockAccountRetriever{}).
|
||||
WithOutput(io.Discard).
|
||||
WithChainID("test-chain")
|
||||
|
||||
ctxGen := func() client.Context {
|
||||
bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{})
|
||||
c := clitestutil.NewMockCometRPC(abci.ResponseQuery{
|
||||
Value: bz,
|
||||
})
|
||||
|
||||
return s.baseCtx.WithClient(c)
|
||||
}
|
||||
s.clientCtx = ctxGen()
|
||||
|
||||
k, _, err := s.clientCtx.Keyring.NewMnemonic("NewValidator", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
pub, err := k.GetPubKey()
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.pub = pub
|
||||
s.addr = sdk.AccAddress(pub.Address())
|
||||
}
|
||||
|
||||
func (s *CLITestSuite) TestNewUnjailTxCmd() {
|
||||
val := s.addr
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErrMsg string
|
||||
}{
|
||||
{
|
||||
"valid transaction",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), // sync mode as there are no funds yet
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(10))).String()),
|
||||
},
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.NewUnjailTxCmd(address.NewBech32Codec("cosmosvaloper"))
|
||||
clientCtx := s.clientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErrMsg != "" {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
txResp := &sdk.TxResponse{}
|
||||
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), txResp), out.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
modulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
@ -21,7 +20,6 @@ import (
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/simulation"
|
||||
@ -85,11 +83,6 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *g
|
||||
}
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the slashing module.
|
||||
func (b AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd(b.cdc.InterfaceRegistry().SigningContext().ValidatorAddressCodec())
|
||||
}
|
||||
|
||||
// AppModule implements an application module for the slashing module.
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
|
||||
Loading…
Reference in New Issue
Block a user