mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +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{},
|
staking.AppModuleBasic{},
|
||||||
mint.AppModuleBasic{},
|
mint.AppModuleBasic{},
|
||||||
distr.AppModuleBasic{},
|
distr.AppModuleBasic{},
|
||||||
gov.NewAppModuleBasic(paramsclient.ProposalHandler, distr.ProposalHandler),
|
gov.NewAppModuleBasic(paramsclient.ProposalHandler, distr.ProposalHandler, committee.ProposalHandler),
|
||||||
params.AppModuleBasic{},
|
params.AppModuleBasic{},
|
||||||
crisis.AppModuleBasic{},
|
crisis.AppModuleBasic{},
|
||||||
slashing.AppModuleBasic{},
|
slashing.AppModuleBasic{},
|
||||||
@ -207,11 +207,23 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
|||||||
invCheckPeriod,
|
invCheckPeriod,
|
||||||
app.supplyKeeper,
|
app.supplyKeeper,
|
||||||
auth.FeeCollectorName)
|
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 := gov.NewRouter()
|
||||||
govRouter.
|
govRouter.
|
||||||
AddRoute(gov.RouterKey, gov.ProposalHandler).
|
AddRoute(gov.RouterKey, gov.ProposalHandler).
|
||||||
AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
|
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.govKeeper = gov.NewKeeper(
|
||||||
app.cdc,
|
app.cdc,
|
||||||
keys[gov.StoreKey],
|
keys[gov.StoreKey],
|
||||||
@ -246,12 +258,6 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
|||||||
app.auctionKeeper,
|
app.auctionKeeper,
|
||||||
app.supplyKeeper,
|
app.supplyKeeper,
|
||||||
cdp.DefaultCodespace)
|
cdp.DefaultCodespace)
|
||||||
app.committeeKeeper = committee.NewKeeper(
|
|
||||||
app.cdc,
|
|
||||||
keys[committee.StoreKey],
|
|
||||||
govRouter,
|
|
||||||
// TODO blacklist module addresses?
|
|
||||||
)
|
|
||||||
|
|
||||||
// register the staking hooks
|
// register the staking hooks
|
||||||
// NOTE: stakingKeeper above is passed by reference, so that it will contain these 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
|
// initialize the app
|
||||||
app.SetInitChainer(app.InitChainer)
|
app.SetInitChainer(app.InitChainer)
|
||||||
app.SetBeginBlocker(app.BeginBlocker)
|
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)
|
app.SetEndBlocker(app.EndBlocker)
|
||||||
|
|
||||||
// load store
|
// load store
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package committee
|
package committee
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/kava-labs/kava/x/committee/client"
|
||||||
"github.com/kava-labs/kava/x/committee/keeper"
|
"github.com/kava-labs/kava/x/committee/keeper"
|
||||||
"github.com/kava-labs/kava/x/committee/types"
|
"github.com/kava-labs/kava/x/committee/types"
|
||||||
)
|
)
|
||||||
@ -49,6 +50,7 @@ var (
|
|||||||
Uint64FromBytes = types.Uint64FromBytes
|
Uint64FromBytes = types.Uint64FromBytes
|
||||||
|
|
||||||
// variable aliases
|
// variable aliases
|
||||||
|
ProposalHandler = client.ProposalHandler
|
||||||
CommitteeKeyPrefix = types.CommitteeKeyPrefix
|
CommitteeKeyPrefix = types.CommitteeKeyPrefix
|
||||||
MaxProposalDuration = types.MaxProposalDuration
|
MaxProposalDuration = types.MaxProposalDuration
|
||||||
ModuleCdc = types.ModuleCdc
|
ModuleCdc = types.ModuleCdc
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"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"
|
"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])
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
|
"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"
|
"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 {
|
func GetCmdVote(cdc *codec.Codec) *cobra.Command {
|
||||||
return &cobra.Command{
|
return &cobra.Command{
|
||||||
Use: "vote [proposal-id]",
|
Use: "vote [proposal-id]",
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(1),
|
||||||
Short: "Vote for an active proposal", // TODO
|
Short: "Vote for an active proposal", // TODO
|
||||||
// Long: strings.TrimSpace(
|
// Long: strings.TrimSpace(
|
||||||
// fmt.Sprintf(`Submit a vote for an active proposal. You can
|
// 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 (
|
import (
|
||||||
"fmt"
|
"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/client/context"
|
||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"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"
|
"github.com/kava-labs/kava/x/committee/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ func queryProposerHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query
|
// Query
|
||||||
res, err := client.QueryProposer(cliCtx, proposalID)
|
res, err := common.QueryProposer(cliCtx, proposalID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
|
"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"
|
"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})
|
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 {
|
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.
|
// 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.
|
// 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.
|
router.Seal()
|
||||||
sealGovRouterIdempotently(router)
|
|
||||||
|
|
||||||
return Keeper{
|
return Keeper{
|
||||||
cdc: cdc,
|
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 ----------
|
// ---------- Committees ----------
|
||||||
|
|
||||||
// GetCommittee gets a committee from the store.
|
// GetCommittee gets a committee from the store.
|
||||||
|
@ -70,6 +70,7 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
|
|||||||
"A proposal description.",
|
"A proposal description.",
|
||||||
committee.Committee{
|
committee.Committee{
|
||||||
ID: 34,
|
ID: 34,
|
||||||
|
Members: suite.addresses[:1],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
expectPass: true,
|
expectPass: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user