mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 06:48:03 +00:00 
			
		
		
		
	add gov client handlers
This commit is contained in:
		
							parent
							
								
									0275b21173
								
							
						
					
					
						commit
						b31cfbe39b
					
				
							
								
								
									
										25
									
								
								app/app.go
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								app/app.go
									
									
									
									
									
								
							@ -55,7 +55,7 @@ var (
 | 
			
		||||
		staking.AppModuleBasic{},
 | 
			
		||||
		mint.AppModuleBasic{},
 | 
			
		||||
		distr.AppModuleBasic{},
 | 
			
		||||
		gov.NewAppModuleBasic(paramsclient.ProposalHandler, distr.ProposalHandler),
 | 
			
		||||
		gov.NewAppModuleBasic(paramsclient.ProposalHandler, distr.ProposalHandler, committee.ProposalHandler),
 | 
			
		||||
		params.AppModuleBasic{},
 | 
			
		||||
		crisis.AppModuleBasic{},
 | 
			
		||||
		slashing.AppModuleBasic{},
 | 
			
		||||
@ -207,11 +207,23 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
 | 
			
		||||
		invCheckPeriod,
 | 
			
		||||
		app.supplyKeeper,
 | 
			
		||||
		auth.FeeCollectorName)
 | 
			
		||||
	committeeGovRouter := gov.NewRouter()
 | 
			
		||||
	committeeGovRouter.
 | 
			
		||||
		AddRoute(gov.RouterKey, gov.ProposalHandler).
 | 
			
		||||
		AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
 | 
			
		||||
		AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper))
 | 
			
		||||
	// Note: the committee proposal handler is not registered on the committee router. This means committees cannot create or update other committees.
 | 
			
		||||
	// Adding the committee proposal handler to the router is possible but awkward as the handler depends on the keeper which depends on the handler.
 | 
			
		||||
	app.committeeKeeper = committee.NewKeeper(
 | 
			
		||||
		app.cdc,
 | 
			
		||||
		keys[committee.StoreKey],
 | 
			
		||||
		committeeGovRouter) // TODO blacklist module addresses?)
 | 
			
		||||
	govRouter := gov.NewRouter()
 | 
			
		||||
	govRouter.
 | 
			
		||||
		AddRoute(gov.RouterKey, gov.ProposalHandler).
 | 
			
		||||
		AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
 | 
			
		||||
		AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper))
 | 
			
		||||
		AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper)).
 | 
			
		||||
		AddRoute(committee.RouterKey, committee.NewProposalHandler(app.committeeKeeper))
 | 
			
		||||
	app.govKeeper = gov.NewKeeper(
 | 
			
		||||
		app.cdc,
 | 
			
		||||
		keys[gov.StoreKey],
 | 
			
		||||
@ -246,12 +258,6 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
 | 
			
		||||
		app.auctionKeeper,
 | 
			
		||||
		app.supplyKeeper,
 | 
			
		||||
		cdp.DefaultCodespace)
 | 
			
		||||
	app.committeeKeeper = committee.NewKeeper(
 | 
			
		||||
		app.cdc,
 | 
			
		||||
		keys[committee.StoreKey],
 | 
			
		||||
		govRouter,
 | 
			
		||||
		// TODO blacklist module addresses?
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// register the staking hooks
 | 
			
		||||
	// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
 | 
			
		||||
@ -330,7 +336,8 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
 | 
			
		||||
	// initialize the app
 | 
			
		||||
	app.SetInitChainer(app.InitChainer)
 | 
			
		||||
	app.SetBeginBlocker(app.BeginBlocker)
 | 
			
		||||
	// app.SetAnteHandler(NewAnteHandler(app.accountKeeper, app.supplyKeeper, app.shutdownKeeper, auth.DefaultSigVerificationGasConsumer))
 | 
			
		||||
	// TODO app.SetAnteHandler(NewAnteHandler(app.accountKeeper, app.supplyKeeper, app.shutdownKeeper, auth.DefaultSigVerificationGasConsumer))
 | 
			
		||||
	app.SetAnteHandler(auth.NewAnteHandler(app.accountKeeper, app.supplyKeeper, auth.DefaultSigVerificationGasConsumer))
 | 
			
		||||
	app.SetEndBlocker(app.EndBlocker)
 | 
			
		||||
 | 
			
		||||
	// load store
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@
 | 
			
		||||
package committee
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/client"
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/keeper"
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/types"
 | 
			
		||||
)
 | 
			
		||||
@ -49,6 +50,7 @@ var (
 | 
			
		||||
	Uint64FromBytes            = types.Uint64FromBytes
 | 
			
		||||
 | 
			
		||||
	// variable aliases
 | 
			
		||||
	ProposalHandler     = client.ProposalHandler
 | 
			
		||||
	CommitteeKeyPrefix  = types.CommitteeKeyPrefix
 | 
			
		||||
	MaxProposalDuration = types.MaxProposalDuration
 | 
			
		||||
	ModuleCdc           = types.ModuleCdc
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ import (
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/client/context"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/codec"
 | 
			
		||||
 | 
			
		||||
	comclient "github.com/kava-labs/kava/x/committee/client"
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/client/common"
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -381,7 +381,7 @@ func GetCmdQueryProposer(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
			
		||||
				return fmt.Errorf("proposal-id %s is not a valid uint", args[0])
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			prop, err := comclient.QueryProposer(cliCtx, proposalID)
 | 
			
		||||
			prop, err := common.QueryProposer(cliCtx, proposalID)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ import (
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
 | 
			
		||||
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
 | 
			
		||||
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/types"
 | 
			
		||||
)
 | 
			
		||||
@ -139,7 +140,7 @@ func GetCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
 | 
			
		||||
func GetCmdVote(cdc *codec.Codec) *cobra.Command {
 | 
			
		||||
	return &cobra.Command{
 | 
			
		||||
		Use:   "vote [proposal-id]",
 | 
			
		||||
		Args:  cobra.ExactArgs(2),
 | 
			
		||||
		Args:  cobra.ExactArgs(1),
 | 
			
		||||
		Short: "Vote for an active proposal", // TODO
 | 
			
		||||
		// 		Long: strings.TrimSpace(
 | 
			
		||||
		// 			fmt.Sprintf(`Submit a vote for an active proposal. You can
 | 
			
		||||
@ -175,3 +176,51 @@ func GetCmdVote(cdc *codec.Codec) *cobra.Command {
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO this could replace the whole gov submit-proposal cmd, remove and replace the gov cmd in kvcli main.go
 | 
			
		||||
// would want the documentation/examples though
 | 
			
		||||
func GetGovCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
 | 
			
		||||
	cmd := &cobra.Command{
 | 
			
		||||
		Use:   "committee [proposal-file] [deposit]",
 | 
			
		||||
		Short: "Submit a governance proposal to change a committee.",
 | 
			
		||||
		Long:  "This command will work with either CommitteeChange proposals or CommitteeDelete proposals.", // TODO
 | 
			
		||||
		Args:  cobra.ExactArgs(2),
 | 
			
		||||
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
			
		||||
			txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
 | 
			
		||||
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
			
		||||
 | 
			
		||||
			// Get proposing address
 | 
			
		||||
			proposer := cliCtx.GetFromAddress()
 | 
			
		||||
 | 
			
		||||
			// Get the deposit
 | 
			
		||||
			deposit, err := sdk.ParseCoins(args[0])
 | 
			
		||||
			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 := cdc.UnmarshalJSON(bz, &content); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			if err = content.ValidateBasic(); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Build message and run basic validation
 | 
			
		||||
			msg := govtypes.NewMsgSubmitProposal(content, deposit, proposer)
 | 
			
		||||
			err = msg.ValidateBasic()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Sign and broadcast message
 | 
			
		||||
			return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
package client
 | 
			
		||||
package common
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
							
								
								
									
										11
									
								
								x/committee/client/proposal_handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								x/committee/client/proposal_handler.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
package client
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
 | 
			
		||||
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/client/cli"
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/client/rest"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ProposalHandler is a struct containing handler funcs for submiting CommitteeChange/Delete proposal txs to the gov module through the cli or rest.
 | 
			
		||||
var ProposalHandler = govclient.NewProposalHandler(cli.GetGovCmdSubmitProposal, rest.ProposalRESTHandler)
 | 
			
		||||
@ -10,7 +10,7 @@ import (
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/client/context"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/types/rest"
 | 
			
		||||
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/client"
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/client/common"
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -181,7 +181,7 @@ func queryProposerHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Query
 | 
			
		||||
		res, err := client.QueryProposer(cliCtx, proposalID)
 | 
			
		||||
		res, err := common.QueryProposer(cliCtx, proposalID)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
 | 
			
		||||
			return
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,8 @@ import (
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/types/rest"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
 | 
			
		||||
	govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest"
 | 
			
		||||
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
 | 
			
		||||
 | 
			
		||||
	"github.com/kava-labs/kava/x/committee/types"
 | 
			
		||||
)
 | 
			
		||||
@ -108,3 +110,46 @@ func postVoteHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
 | 
			
		||||
		utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// -------- --------
 | 
			
		||||
// TODO this could replace the POST gov/proposals endpoint, would need to overwrite routes in kvcli main, hacky
 | 
			
		||||
type PostGovProposalReq struct {
 | 
			
		||||
	BaseReq  rest.BaseReq     `json:"base_req" yaml:"base_req"`
 | 
			
		||||
	Content  govtypes.Content `json:"content" yaml:"content"` //TODO use same PubProposal name?
 | 
			
		||||
	Proposer sdk.AccAddress   `json:"proposer" yaml:"proposer"`
 | 
			
		||||
	Deposit  sdk.Coins        `json:"deposit" yaml:"deposit"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ProposalRESTHandler(cliCtx context.CLIContext) govrest.ProposalRESTHandler {
 | 
			
		||||
	return govrest.ProposalRESTHandler{
 | 
			
		||||
		SubRoute: "committee",
 | 
			
		||||
		Handler:  postGovProposalHandlerFn(cliCtx),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func postGovProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
		// Parse and validate http request body
 | 
			
		||||
		var req PostGovProposalReq
 | 
			
		||||
		if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		req.BaseReq = req.BaseReq.Sanitize()
 | 
			
		||||
		if !req.BaseReq.ValidateBasic(w) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if err := req.Content.ValidateBasic(); err != nil {
 | 
			
		||||
			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Create and return a StdTx
 | 
			
		||||
		msg := govtypes.NewMsgSubmitProposal(req.Content, req.Deposit, req.Proposer)
 | 
			
		||||
		if err := msg.ValidateBasic(); err != nil {
 | 
			
		||||
			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		utils.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,8 +22,7 @@ type Keeper struct {
 | 
			
		||||
func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, router govtypes.Router) Keeper {
 | 
			
		||||
	// Logic in the keeper methods assume the set of gov handlers is fixed.
 | 
			
		||||
	// So the gov router must be sealed so no handlers can be added or removed after the keeper is created.
 | 
			
		||||
	// Note: for some reason the gov router panics if it has already been sealed, so a helper func is used to make sealing idempotent.
 | 
			
		||||
	sealGovRouterIdempotently(router)
 | 
			
		||||
	router.Seal()
 | 
			
		||||
 | 
			
		||||
	return Keeper{
 | 
			
		||||
		cdc:      cdc,
 | 
			
		||||
@ -32,13 +31,6 @@ func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, router govtypes.Router)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sealGovRouterIdempotently(router govtypes.Router) {
 | 
			
		||||
	defer func() {
 | 
			
		||||
		recover()
 | 
			
		||||
	}()
 | 
			
		||||
	router.Seal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ---------- Committees ----------
 | 
			
		||||
 | 
			
		||||
// GetCommittee gets a committee from the store.
 | 
			
		||||
 | 
			
		||||
@ -70,6 +70,7 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
 | 
			
		||||
				"A proposal description.",
 | 
			
		||||
				committee.Committee{
 | 
			
		||||
					ID:      34,
 | 
			
		||||
					Members: suite.addresses[:1],
 | 
			
		||||
				},
 | 
			
		||||
			),
 | 
			
		||||
			expectPass: true,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user