package rest import ( "net/http" "time" "github.com/gorilla/mux" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/upgrade/internal/types" ) func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc("/upgrade/plan", postPlanHandler(cliCtx)).Methods("POST") r.HandleFunc("/upgrade/cancel", cancelPlanHandler(cliCtx)).Methods("POST") } // PlanRequest defines a proposal for a new upgrade plan. type PlanRequest struct { BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` Title string `json:"title" yaml:"title"` Description string `json:"description" yaml:"description"` Deposit sdk.Coins `json:"deposit" yaml:"deposit"` UpgradeName string `json:"upgrade_name" yaml:"upgrade_name"` UpgradeHeight int64 `json:"upgrade_height" yaml:"upgrade_height"` UpgradeTime string `json:"upgrade_time" yaml:"upgrade_time"` UpgradeInfo string `json:"upgrade_info" yaml:"upgrade_info"` } // CancelRequest defines a proposal to cancel a current plan. type CancelRequest struct { BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` Title string `json:"title" yaml:"title"` Description string `json:"description" yaml:"description"` Deposit sdk.Coins `json:"deposit" yaml:"deposit"` } func ProposalRESTHandler(cliCtx context.CLIContext) govrest.ProposalRESTHandler { return govrest.ProposalRESTHandler{ SubRoute: "upgrade", Handler: postPlanHandler(cliCtx), } } func postPlanHandler(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req PlanRequest if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { return } req.BaseReq = req.BaseReq.Sanitize() if !req.BaseReq.ValidateBasic(w) { return } fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } var t time.Time if req.UpgradeTime != "" { t, err = time.Parse(time.RFC3339, req.UpgradeTime) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } } plan := types.Plan{Name: req.UpgradeName, Time: t, Height: req.UpgradeHeight, Info: req.UpgradeInfo} content := types.NewSoftwareUpgradeProposal(req.Title, req.Description, plan) msg := gov.NewMsgSubmitProposal(content, req.Deposit, fromAddr) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } func cancelPlanHandler(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req CancelRequest if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { return } req.BaseReq = req.BaseReq.Sanitize() if !req.BaseReq.ValidateBasic(w) { return } fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } content := types.NewCancelSoftwareUpgradeProposal(req.Title, req.Description) msg := gov.NewMsgSubmitProposal(content, req.Deposit, fromAddr) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } }