mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 00:27:41 +00:00 
			
		
		
		
	- Upgrade cosmos-sdk to v0.44.5 from v0.39.2 - Add Legacy Tx Endpoint for backwards compatibility - Add IBC v1.2.3 Support Co-authored-by: DracoLi <draco@dracoli.com> Co-authored-by: drklee3 <derrick@dlee.dev> Co-authored-by: denalimarsh <denalimarsh@gmail.com> Co-authored-by: Draco Li <draco@kava.io> Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> Co-authored-by: Denali Marsh <denali@kava.io>
		
			
				
	
	
		
			323 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			323 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package cli
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"io/ioutil"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/spf13/cobra"
 | 
						|
	"github.com/tendermint/tendermint/crypto"
 | 
						|
 | 
						|
	"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/codec"
 | 
						|
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						|
	"github.com/cosmos/cosmos-sdk/version"
 | 
						|
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
 | 
						|
	paramsproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
 | 
						|
 | 
						|
	"github.com/kava-labs/kava/x/committee/types"
 | 
						|
)
 | 
						|
 | 
						|
const PARAMS_CHANGE_PROPOSAL_EXAMPLE = `
 | 
						|
{
 | 
						|
  "title": "title",
 | 
						|
  "description": "description",
 | 
						|
  "changes": [{ "subspace": "subspace", "key": "key", "value": "value" }]
 | 
						|
}
 | 
						|
`
 | 
						|
 | 
						|
const COMMITTEE_CHANGE_PROPOSAL_EXAMPLE = `
 | 
						|
{
 | 
						|
  "title": "A Title",
 | 
						|
  "description": "A proposal description.",
 | 
						|
  "new_committee": {
 | 
						|
    "@type": "/kava.committee.v1beta1.MemberCommittee",
 | 
						|
    "base_committee": {
 | 
						|
      "id": "34",
 | 
						|
      "description": "member committee",
 | 
						|
      "members": ["kava1ze7y9qwdddejmy7jlw4cymqqlt2wh05yhwmrv2"],
 | 
						|
      "permissions": [],
 | 
						|
      "vote_threshold": "1.000000000000000000",
 | 
						|
      "proposal_duration": "86400s",
 | 
						|
      "tally_option": "TALLY_OPTION_DEADLINE"
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
`
 | 
						|
 | 
						|
const COMMITTEE_DELETE_PROPOSAL_EXAMPLE = `
 | 
						|
{
 | 
						|
  "title": "A Title",
 | 
						|
  "description": "A proposal description.",
 | 
						|
  "committee_id": "1"
 | 
						|
}
 | 
						|
`
 | 
						|
 | 
						|
func GetTxCmd() *cobra.Command {
 | 
						|
	txCmd := &cobra.Command{
 | 
						|
		Use:                        types.ModuleName,
 | 
						|
		Short:                      "committee governance transactions subcommands",
 | 
						|
		DisableFlagParsing:         true,
 | 
						|
		SuggestionsMinimumDistance: 2,
 | 
						|
		RunE:                       client.ValidateCmd,
 | 
						|
	}
 | 
						|
 | 
						|
	cmds := []*cobra.Command{
 | 
						|
		getCmdVote(),
 | 
						|
		getCmdSubmitProposal(),
 | 
						|
	}
 | 
						|
 | 
						|
	for _, cmd := range cmds {
 | 
						|
		flags.AddTxFlagsToCmd(cmd)
 | 
						|
	}
 | 
						|
 | 
						|
	txCmd.AddCommand(cmds...)
 | 
						|
 | 
						|
	return txCmd
 | 
						|
}
 | 
						|
 | 
						|
// getCmdSubmitProposal returns the command to submit a proposal to a committee
 | 
						|
func getCmdSubmitProposal() *cobra.Command {
 | 
						|
	cmd := &cobra.Command{
 | 
						|
		Use:   "submit-proposal [committee-id] [proposal-file]",
 | 
						|
		Short: "Submit a governance proposal to a particular committee",
 | 
						|
		Long: fmt.Sprintf(`Submit a proposal to a committee so they can vote on it.
 | 
						|
 | 
						|
The proposal file must be the json encoded forms of the proposal type you want to submit.
 | 
						|
For example:
 | 
						|
%s
 | 
						|
`, PARAMS_CHANGE_PROPOSAL_EXAMPLE),
 | 
						|
		Args:    cobra.ExactArgs(2),
 | 
						|
		Example: fmt.Sprintf("%s tx %s submit-proposal 1 your-proposal.json", version.AppName, types.ModuleName),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			clientCtx, err := client.GetClientTxContext(cmd)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Get proposing address
 | 
						|
			proposer := clientCtx.GetFromAddress()
 | 
						|
 | 
						|
			// Get committee ID
 | 
						|
			committeeID, err := strconv.ParseUint(args[0], 10, 64)
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("committee-id %s not a valid int", args[0])
 | 
						|
			}
 | 
						|
 | 
						|
			// Get proposal content
 | 
						|
			var pubProposal types.PubProposal
 | 
						|
			contents, err := ioutil.ReadFile(args[1])
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			if err := clientCtx.Codec.UnmarshalInterfaceJSON(contents, &pubProposal); err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			if err = pubProposal.ValidateBasic(); err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Build message and run basic validation
 | 
						|
			msg, err := types.NewMsgSubmitProposal(pubProposal, proposer, committeeID)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			err = msg.ValidateBasic()
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Sign and broadcast message
 | 
						|
			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	return cmd
 | 
						|
}
 | 
						|
 | 
						|
// getCmdVote returns the command to vote on a proposal.
 | 
						|
func getCmdVote() *cobra.Command {
 | 
						|
	return &cobra.Command{
 | 
						|
		Use:     "vote [proposal-id] [vote]",
 | 
						|
		Args:    cobra.ExactArgs(2),
 | 
						|
		Short:   "Vote for an active proposal",
 | 
						|
		Long:    "Submit a [yes/no/abstain] vote for the proposal with id [proposal-id].",
 | 
						|
		Example: fmt.Sprintf("%s tx %s vote 2 yes", version.AppName, types.ModuleName),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			clientCtx, err := client.GetClientTxContext(cmd)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Get voting address
 | 
						|
			from := clientCtx.GetFromAddress()
 | 
						|
 | 
						|
			// validate that the proposal id is a uint
 | 
						|
			proposalID, err := strconv.ParseUint(args[0], 10, 64)
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0])
 | 
						|
			}
 | 
						|
 | 
						|
			rawVote := strings.ToLower(strings.TrimSpace(args[1]))
 | 
						|
			if len(rawVote) == 0 {
 | 
						|
				return fmt.Errorf("must specify a vote")
 | 
						|
			}
 | 
						|
 | 
						|
			var vote types.VoteType
 | 
						|
			switch rawVote {
 | 
						|
			case "yes", "y":
 | 
						|
				vote = types.VOTE_TYPE_YES
 | 
						|
			case "no", "n":
 | 
						|
				vote = types.VOTE_TYPE_NO
 | 
						|
			case "abstain", "a":
 | 
						|
				vote = types.VOTE_TYPE_ABSTAIN
 | 
						|
			default:
 | 
						|
				return fmt.Errorf("must specify a valid vote type: (yes/y, no/n, abstain/a)")
 | 
						|
			}
 | 
						|
 | 
						|
			// Build vote message and run basic validation
 | 
						|
			msg := types.NewMsgVote(from, proposalID, vote)
 | 
						|
			err = msg.ValidateBasic()
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// GetGovCmdSubmitProposal returns a command to submit a proposal to the gov module. It is passed to the gov module for use on its command subtree.
 | 
						|
func GetGovCmdSubmitProposal() *cobra.Command {
 | 
						|
	cmd := &cobra.Command{
 | 
						|
		Use:   "committee [proposal-file] [deposit]",
 | 
						|
		Short: "Submit a governance proposal to change a committee.",
 | 
						|
		Long: fmt.Sprintf(`Submit a governance proposal to create, alter, or delete a committee.
 | 
						|
 | 
						|
The proposal file must be the json encoded form of the proposal type you want to submit.
 | 
						|
For example, to create or update a committee:
 | 
						|
%s
 | 
						|
 | 
						|
and to delete a committee:
 | 
						|
%s
 | 
						|
`, COMMITTEE_CHANGE_PROPOSAL_EXAMPLE, COMMITTEE_DELETE_PROPOSAL_EXAMPLE),
 | 
						|
		Args: cobra.ExactArgs(2),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			clientCtx, err := client.GetClientTxContext(cmd)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Get proposing address
 | 
						|
			proposer := clientCtx.GetFromAddress()
 | 
						|
 | 
						|
			// Get the deposit
 | 
						|
			deposit, err := sdk.ParseCoinsNormalized(args[1])
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Get the proposal
 | 
						|
			bz, err := ioutil.ReadFile(args[0])
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			var content govtypes.Content
 | 
						|
			if err := clientCtx.Codec.UnmarshalInterfaceJSON(bz, &content); err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			if err = content.ValidateBasic(); err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Build message and run basic validation
 | 
						|
			msg, err := govtypes.NewMsgSubmitProposal(content, deposit, proposer)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			err = msg.ValidateBasic()
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Sign and broadcast message
 | 
						|
			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
 | 
						|
		},
 | 
						|
	}
 | 
						|
	return cmd
 | 
						|
}
 | 
						|
 | 
						|
// MustGetExampleCommitteeChangeProposal is a helper function to return an example json proposal
 | 
						|
func MustGetExampleCommitteeChangeProposal(cdc codec.Codec) string {
 | 
						|
	exampleChangeProposal, err := types.NewCommitteeChangeProposal(
 | 
						|
		"A Title",
 | 
						|
		"A description of this proposal.",
 | 
						|
		types.MustNewMemberCommittee(
 | 
						|
			1,
 | 
						|
			"The description of this committee.",
 | 
						|
			[]sdk.AccAddress{sdk.AccAddress(crypto.AddressHash([]byte("exampleAddress")))},
 | 
						|
			[]types.Permission{
 | 
						|
				&types.GodPermission{},
 | 
						|
			},
 | 
						|
			sdk.MustNewDecFromStr("0.8"),
 | 
						|
			time.Hour*24*7,
 | 
						|
			types.TALLY_OPTION_FIRST_PAST_THE_POST,
 | 
						|
		),
 | 
						|
	)
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	exampleChangeProposalBz, err := cdc.MarshalJSON(&exampleChangeProposal)
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	var out bytes.Buffer
 | 
						|
	if err = json.Indent(&out, exampleChangeProposalBz, "", "  "); err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	return out.String()
 | 
						|
}
 | 
						|
 | 
						|
// MustGetExampleCommitteeDeleteProposal is a helper function to return an example json proposal
 | 
						|
func MustGetExampleCommitteeDeleteProposal(cdc codec.Codec) string {
 | 
						|
	exampleDeleteProposal := types.NewCommitteeDeleteProposal(
 | 
						|
		"A Title",
 | 
						|
		"A description of this proposal.",
 | 
						|
		1,
 | 
						|
	)
 | 
						|
	bz, err := cdc.MarshalJSON(&exampleDeleteProposal)
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	var out bytes.Buffer
 | 
						|
	if err = json.Indent(&out, bz, "", "  "); err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	return out.String()
 | 
						|
}
 | 
						|
 | 
						|
// MustGetExampleParameterChangeProposal is a helper function to return an example json proposal
 | 
						|
func MustGetExampleParameterChangeProposal(cdc codec.Codec) string {
 | 
						|
	value := fmt.Sprintf("\"%d\"", 1000000000)
 | 
						|
	exampleParameterChangeProposal := paramsproposal.NewParameterChangeProposal(
 | 
						|
		"A Title",
 | 
						|
		"A description of this proposal.",
 | 
						|
		[]paramsproposal.ParamChange{paramsproposal.NewParamChange("cdp", "SurplusAuctionThreshold", value)},
 | 
						|
	)
 | 
						|
	bz, err := cdc.MarshalJSON(exampleParameterChangeProposal)
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	var out bytes.Buffer
 | 
						|
	if err = json.Indent(&out, bz, "", "  "); err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	return out.String()
 | 
						|
}
 |