From ef4d6d5844e7cee05353910f001fb338b3f5692d Mon Sep 17 00:00:00 2001 From: Youngtaek Yoon Date: Thu, 14 Sep 2023 13:10:57 +0000 Subject: [PATCH] feat: add update-censorship cmd to x/foundation cli (#1121) * Add update-censorship to tx cli * Update CHANGELOG.md * Lint * Add normalizer * Lint --- CHANGELOG.md | 1 + x/foundation/client/cli/tx.go | 74 ++++++++++++++++++++++++++++++ x/foundation/client/testutil/tx.go | 63 +++++++++++++++++++++++++ 3 files changed, 138 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fccb7edef..c70697c499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements * (types) [\#1314](https://github.com/Finschia/finschia-sdk/pull/1314) replace IsEqual with Equal * (docs) [\#1120](https://github.com/Finschia/finschia-sdk/pull/1120) Update links in x/foundation README.md +* (feat) [\#1121](https://github.com/Finschia/finschia-sdk/pull/1121) Add update-censorship cmd to x/foundation cli ### Bug Fixes * (x/auth) [#1281](https://github.com/Finschia/finschia-sdk/pull/1281) `ModuleAccount.Validate` now reports a nil `.BaseAccount` instead of panicking. (backport #1274) diff --git a/x/foundation/client/cli/tx.go b/x/foundation/client/cli/tx.go index bc4eddad12..e654e0f887 100644 --- a/x/foundation/client/cli/tx.go +++ b/x/foundation/client/cli/tx.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "strconv" + "strings" "github.com/spf13/cobra" @@ -91,6 +92,22 @@ func execFromString(execStr string) foundation.Exec { return exec } +func normalizeCensorshipAuthority(option string) string { + prefix := getEnumPrefix(foundation.CensorshipAuthority_name[0]) + candidate := strings.ToUpper(prefix + option) + if _, ok := foundation.CensorshipAuthority_value[candidate]; ok { + return candidate + } + + return option +} + +func getEnumPrefix(str string) string { + delimiter := "_" + splitted := strings.Split(str, delimiter) + return strings.Join(splitted[:len(splitted)-1], delimiter) + delimiter +} + // VoteOptionFromString returns a VoteOption from a string. It returns an error // if the string is invalid. func voteOptionFromString(str string) (foundation.VoteOption, error) { @@ -101,6 +118,15 @@ func voteOptionFromString(str string) (foundation.VoteOption, error) { return foundation.VoteOption(vo), nil } +// CensorshipAuthorityFromString returns a CensorshipAuthority from a string. It returns an error if the string is invalid. +func censorshipAuthorityFromString(str string) (foundation.CensorshipAuthority, error) { + ca, ok := foundation.CensorshipAuthority_value[str] + if !ok { + return foundation.CensorshipAuthorityUnspecified, fmt.Errorf("'%s' is not a valid censorship authority", str) + } + return foundation.CensorshipAuthority(ca), nil +} + func parseMsgs(cdc codec.Codec, msgsJSON string) ([]sdk.Msg, error) { var cliMsgs []json.RawMessage if err := json.Unmarshal([]byte(msgsJSON), &cliMsgs); err != nil { @@ -549,6 +575,54 @@ func NewTxCmdExec() *cobra.Command { return cmd } +func NewTxCmdUpdateCensorship() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-censorship [authority] [msg-type-url] [new-authority]", + Args: cobra.ExactArgs(3), + Short: "Update censorship over a message", + Long: `Update censorship over a message + +Parameters: + authority: the current authority of the censorship + msg-type-url: the message type url of the censorship + new-authority: a new authority of the censorship + unspecified: no authority, which means removing the censorship + governance: x/gov + foundation: x/foundation +`, + RunE: func(cmd *cobra.Command, args []string) error { + if err := validateGenerateOnly(cmd); err != nil { + return err + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + newAuthority, err := censorshipAuthorityFromString(normalizeCensorshipAuthority(args[2])) + if err != nil { + return err + } + + msg := foundation.MsgUpdateCensorship{ + Authority: args[0], + Censorship: foundation.Censorship{ + MsgTypeUrl: args[1], + Authority: newAuthority, + }, + } + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + func NewTxCmdLeaveFoundation() *cobra.Command { cmd := &cobra.Command{ Use: "leave-foundation [address]", diff --git a/x/foundation/client/testutil/tx.go b/x/foundation/client/testutil/tx.go index 36f7169dc6..ccc283cb8c 100644 --- a/x/foundation/client/testutil/tx.go +++ b/x/foundation/client/testutil/tx.go @@ -420,6 +420,69 @@ func (s *IntegrationTestSuite) TestNewTxCmdExec() { } } +func (s *IntegrationTestSuite) TestNewTxCmdUpdateCensorship() { + val := s.network.Validators[0] + commonArgs := []string{ + fmt.Sprintf("--%s", flags.FlagGenerateOnly), + } + + testCases := map[string]struct { + args []string + valid bool + }{ + "valid transaction": { + []string{ + s.authority.String(), + foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), + foundation.CensorshipAuthorityGovernance.String(), + }, + true, + }, + "valid abbreviation": { + []string{ + s.authority.String(), + foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), + "governance", + }, + true, + }, + "wrong number of args": { + []string{ + s.authority.String(), + foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), + foundation.CensorshipAuthorityGovernance.String(), + "extra", + }, + false, + }, + "invalid new authority": { + []string{ + s.authority.String(), + foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), + "invalid-new-authority", + }, + false, + }, + } + + for name, tc := range testCases { + tc := tc + + s.Run(name, func() { + cmd := cli.NewTxCmdUpdateCensorship() + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, append(tc.args, commonArgs...)) + if !tc.valid { + s.Require().Error(err) + return + } + s.Require().NoError(err) + + var res txtypes.Tx + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &res), out) + }) + } +} + func (s *IntegrationTestSuite) TestNewTxCmdLeaveFoundation() { val := s.network.Validators[0] commonArgs := []string{