diff --git a/app/app.go b/app/app.go index 5d628acf..ba62c3c2 100644 --- a/app/app.go +++ b/app/app.go @@ -4,7 +4,6 @@ import ( "io" "os" - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" @@ -39,7 +38,6 @@ import ( "github.com/kava-labs/kava/x/kavadist" "github.com/kava-labs/kava/x/pricefeed" validatorvesting "github.com/kava-labs/kava/x/validator-vesting" - ) const ( @@ -261,8 +259,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, app.committeeKeeper = committee.NewKeeper( app.cdc, keys[committee.StoreKey], - committeeGovRouter, - committee.DefaultCodespace, // TODO blacklist module addresses?) + committeeGovRouter, // TODO blacklist module addresses? ) // create gov keeper with router @@ -356,7 +353,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, bep3.NewAppModule(app.bep3Keeper, app.accountKeeper, app.supplyKeeper), kavadist.NewAppModule(app.kavadistKeeper, app.supplyKeeper), incentive.NewAppModule(app.incentiveKeeper, app.accountKeeper, app.supplyKeeper), - committee.NewAppModule(app.committeeKeeper), + committee.NewAppModule(app.committeeKeeper, app.accountKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that @@ -364,7 +361,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, // CanWithdrawInvariant invariant. // Auction.BeginBlocker will close out expired auctions and pay debt back to cdp. // So it should be run before cdp.BeginBlocker which cancels out debt with stable and starts more auctions. - app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName, validatorvesting.ModuleName, kavadist.ModuleName, auction.ModuleName, cdp.ModuleName, bep3.ModuleName, incentive.ModuleName committee.ModuleName) + app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName, validatorvesting.ModuleName, kavadist.ModuleName, auction.ModuleName, cdp.ModuleName, bep3.ModuleName, incentive.ModuleName, committee.ModuleName) app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName, pricefeed.ModuleName) @@ -374,7 +371,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, staking.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName, mint.ModuleName, evidence.ModuleName, pricefeed.ModuleName, cdp.ModuleName, auction.ModuleName, - bep3.ModuleName, kavadist.ModuleName, incentive.ModuleName, committee.ModuleName + bep3.ModuleName, kavadist.ModuleName, incentive.ModuleName, committee.ModuleName, supply.ModuleName, // calculates the total supply from account - should run after modules that modify accounts in genesis crisis.ModuleName, // runs the invariants at genesis - should run after other modules genutil.ModuleName, // genutils must occur after staking so that pools are properly initialized with tokens from genesis accounts. diff --git a/x/committee/alias.go b/x/committee/alias.go index 996dddfc..17138e4b 100644 --- a/x/committee/alias.go +++ b/x/committee/alias.go @@ -16,12 +16,6 @@ const ( AttributeValueProposalFailed = types.AttributeValueProposalFailed AttributeValueProposalPassed = types.AttributeValueProposalPassed AttributeValueProposalTimeout = types.AttributeValueProposalTimeout - CodeInvalidCommittee = types.CodeInvalidCommittee - CodeInvalidGenesis = types.CodeInvalidGenesis - CodeInvalidProposal = types.CodeInvalidProposal - CodeProposalExpired = types.CodeProposalExpired - CodeUnknownItem = types.CodeUnknownItem - DefaultCodespace = types.DefaultCodespace DefaultNextProposalID = types.DefaultNextProposalID DefaultParamspace = types.DefaultParamspace EventTypeProposalClose = types.EventTypeProposalClose @@ -50,14 +44,6 @@ var ( NewKeeper = keeper.NewKeeper NewQuerier = keeper.NewQuerier DefaultGenesisState = types.DefaultGenesisState - ErrInvalidCommittee = types.ErrInvalidCommittee - ErrInvalidGenesis = types.ErrInvalidGenesis - ErrInvalidPubProposal = types.ErrInvalidPubProposal - ErrNoProposalHandlerExists = types.ErrNoProposalHandlerExists - ErrProposalExpired = types.ErrProposalExpired - ErrUnknownCommittee = types.ErrUnknownCommittee - ErrUnknownProposal = types.ErrUnknownProposal - ErrUnknownVote = types.ErrUnknownVote GetKeyFromID = types.GetKeyFromID GetVoteKey = types.GetVoteKey NewCommittee = types.NewCommittee @@ -66,6 +52,7 @@ var ( NewGenesisState = types.NewGenesisState NewMsgSubmitProposal = types.NewMsgSubmitProposal NewMsgVote = types.NewMsgVote + NewProposal = types.NewProposal NewQueryCommitteeParams = types.NewQueryCommitteeParams NewQueryProposalParams = types.NewQueryProposalParams NewQueryVoteParams = types.NewQueryVoteParams @@ -75,12 +62,20 @@ var ( Uint64FromBytes = types.Uint64FromBytes // variable aliases - ProposalHandler = client.ProposalHandler - CommitteeKeyPrefix = types.CommitteeKeyPrefix - ModuleCdc = types.ModuleCdc - NextProposalIDKey = types.NextProposalIDKey - ProposalKeyPrefix = types.ProposalKeyPrefix - VoteKeyPrefix = types.VoteKeyPrefix + ProposalHandler = client.ProposalHandler + CommitteeKeyPrefix = types.CommitteeKeyPrefix + ErrInvalidCommittee = types.ErrInvalidCommittee + ErrInvalidGenesis = types.ErrInvalidGenesis + ErrInvalidPubProposal = types.ErrInvalidPubProposal + ErrNoProposalHandlerExists = types.ErrNoProposalHandlerExists + ErrProposalExpired = types.ErrProposalExpired + ErrUnknownCommittee = types.ErrUnknownCommittee + ErrUnknownProposal = types.ErrUnknownProposal + ErrUnknownVote = types.ErrUnknownVote + ModuleCdc = types.ModuleCdc + NextProposalIDKey = types.NextProposalIDKey + ProposalKeyPrefix = types.ProposalKeyPrefix + VoteKeyPrefix = types.VoteKeyPrefix ) type ( @@ -101,5 +96,6 @@ type ( QueryCommitteeParams = types.QueryCommitteeParams QueryProposalParams = types.QueryProposalParams QueryVoteParams = types.QueryVoteParams + TextPermission = types.TextPermission Vote = types.Vote ) diff --git a/x/committee/client/cli/query.go b/x/committee/client/cli/query.go index e97a8499..68928e11 100644 --- a/x/committee/client/cli/query.go +++ b/x/committee/client/cli/query.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/version" @@ -25,7 +26,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - queryCmd.AddCommand(client.GetCommands( + queryCmd.AddCommand(flags.GetCommands( // committees GetCmdQueryCommittee(queryRoute, cdc), GetCmdQueryCommittees(queryRoute, cdc), diff --git a/x/committee/client/cli/tx.go b/x/committee/client/cli/tx.go index e3fbbd94..ea8fc273 100644 --- a/x/committee/client/cli/tx.go +++ b/x/committee/client/cli/tx.go @@ -1,6 +1,7 @@ package cli import ( + "bufio" "fmt" "io/ioutil" "strconv" @@ -10,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -31,7 +33,7 @@ func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - txCmd.AddCommand(client.PostCommands( + txCmd.AddCommand(flags.PostCommands( GetCmdVote(cdc), GetCmdSubmitProposal(cdc), )...) @@ -53,7 +55,8 @@ For example: Args: cobra.ExactArgs(2), Example: fmt.Sprintf("%s tx %s submit-proposal 1 your-proposal.json", version.ClientName, types.ModuleName), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) // Get proposing address @@ -102,7 +105,8 @@ func GetCmdVote(cdc *codec.Codec) *cobra.Command { Long: "Submit a yes vote for the proposal with id [proposal-id].", Example: fmt.Sprintf("%s tx %s vote 2", version.ClientName, types.ModuleName), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) // Get voting address @@ -142,7 +146,8 @@ and to delete a committee: `, MustGetExampleCommitteeChangeProposal(cdc), MustGetExampleCommitteeDeleteProposal(cdc)), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) cliCtx := context.NewCLIContext().WithCodec(cdc) // Get proposing address diff --git a/x/committee/handler.go b/x/committee/handler.go index 23210d43..9129d4e1 100644 --- a/x/committee/handler.go +++ b/x/committee/handler.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/kava-labs/kava/x/committee/keeper" "github.com/kava-labs/kava/x/committee/types" @@ -11,7 +12,7 @@ import ( // NewHandler creates an sdk.Handler for committee messages func NewHandler(k keeper.Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -20,16 +21,15 @@ func NewHandler(k keeper.Keeper) sdk.Handler { case types.MsgVote: return handleMsgVote(ctx, k, msg) default: - errMsg := fmt.Sprintf("unrecognized %s msg type: %T", types.ModuleName, msg) - return sdk.ErrUnknownRequest(errMsg).Result() + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg) } } } -func handleMsgSubmitProposal(ctx sdk.Context, k keeper.Keeper, msg types.MsgSubmitProposal) sdk.Result { +func handleMsgSubmitProposal(ctx sdk.Context, k keeper.Keeper, msg types.MsgSubmitProposal) (*sdk.Result, error) { proposalID, err := k.SubmitProposal(ctx, msg.Proposer, msg.CommitteeID, msg.PubProposal) if err != nil { - return err.Result() + return nil, err } ctx.EventManager().EmitEvent( @@ -40,28 +40,28 @@ func handleMsgSubmitProposal(ctx sdk.Context, k keeper.Keeper, msg types.MsgSubm ), ) - return sdk.Result{ + return &sdk.Result{ Data: GetKeyFromID(proposalID), Events: ctx.EventManager().Events(), - } + }, nil } -func handleMsgVote(ctx sdk.Context, k keeper.Keeper, msg types.MsgVote) sdk.Result { +func handleMsgVote(ctx sdk.Context, k keeper.Keeper, msg types.MsgVote) (*sdk.Result, error) { // get the proposal just to add fields to the event proposal, found := k.GetProposal(ctx, msg.ProposalID) if !found { - return ErrUnknownProposal(DefaultCodespace, msg.ProposalID).Result() + return nil, sdkerrors.Wrapf(ErrUnknownProposal, "%d", msg.ProposalID) } err := k.AddVote(ctx, msg.ProposalID, msg.Voter) if err != nil { - return err.Result() + return nil, err } // Enact a proposal if it has enough votes passes, err := k.GetProposalResult(ctx, msg.ProposalID) if err != nil { - return err.Result() + return nil, err } if passes { err = k.EnactProposal(ctx, msg.ProposalID) @@ -89,5 +89,5 @@ func handleMsgVote(ctx sdk.Context, k keeper.Keeper, msg types.MsgVote) sdk.Resu ), ) - return sdk.Result{Events: ctx.EventManager().Events()} + return &sdk.Result{Events: ctx.EventManager().Events()}, nil } diff --git a/x/committee/handler_test.go b/x/committee/handler_test.go index 69dca714..7ae9d781 100644 --- a/x/committee/handler_test.go +++ b/x/committee/handler_test.go @@ -20,7 +20,7 @@ import ( // NewDistributionGenesisWithPool creates a default distribution genesis state with some coins in the community pool. func NewDistributionGenesisWithPool(communityPoolCoins sdk.Coins) app.GenesisState { gs := distribution.DefaultGenesisState() - gs.FeePool = distribution.FeePool{CommunityPool: sdk.NewDecCoins(communityPoolCoins)} + gs.FeePool = distribution.FeePool{CommunityPool: sdk.NewDecCoinsFromCoins(communityPoolCoins...)} return app.GenesisState{distribution.ModuleName: distribution.ModuleCdc.MustMarshalJSON(gs)} } @@ -81,9 +81,9 @@ func (suite *HandlerTestSuite) TestSubmitProposalMsg_Valid() { 1, ) - res := suite.handler(suite.ctx, msg) + res, err := suite.handler(suite.ctx, msg) - suite.True(res.IsOK()) + suite.NoError(err) _, found := suite.keeper.GetProposal(suite.ctx, types.Uint64FromBytes(res.Data)) suite.True(found) } @@ -104,9 +104,9 @@ func (suite *HandlerTestSuite) TestSubmitProposalMsg_Invalid() { committeeID, ) - res := suite.handler(suite.ctx, msg) + _, err := suite.handler(suite.ctx, msg) - suite.False(res.IsOK()) + suite.Error(err) suite.Empty( suite.keeper.GetProposalsByCommittee(suite.ctx, committeeID), "proposal found when none should exist", @@ -122,9 +122,9 @@ func (suite *HandlerTestSuite) TestSubmitProposalMsg_Unregistered() { committeeID, ) - res := suite.handler(suite.ctx, msg) + _, err := suite.handler(suite.ctx, msg) - suite.False(res.IsOK()) + suite.Error(err) suite.Empty( suite.keeper.GetProposalsByCommittee(suite.ctx, committeeID), "proposal found when none should exist", @@ -147,16 +147,16 @@ func (suite *HandlerTestSuite) TestMsgAddVote_ProposalPass() { suite.addresses[0], 1, ) - res := suite.handler(suite.ctx, msg) - suite.True(res.IsOK()) + res, err := suite.handler(suite.ctx, msg) + suite.NoError(err) proposalID := types.Uint64FromBytes(res.Data) - res = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[0], proposalID)) - suite.True(res.IsOK()) + _, err = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[0], proposalID)) + suite.NoError(err) // Add a vote to make the proposal pass - res = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[1], proposalID)) + _, err = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[1], proposalID)) - suite.True(res.IsOK()) + suite.NoError(err) // Check the param has been updated suite.Equal(newDebtThreshold, suite.app.GetCDPKeeper().GetParams(suite.ctx).DebtAuctionThreshold) // Check proposal and votes are gone @@ -181,19 +181,19 @@ func (suite *HandlerTestSuite) TestMsgAddVote_ProposalFail() { suite.addresses[0], 1, ) - res := suite.handler(suite.ctx, msg) - suite.True(res.IsOK()) + res, err := suite.handler(suite.ctx, msg) + suite.NoError(err) proposalID := types.Uint64FromBytes(res.Data) - res = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[0], proposalID)) - suite.True(res.IsOK()) + _, err = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[0], proposalID)) + suite.NoError(err) // invalidate the proposal by emptying community pool suite.app.GetDistrKeeper().DistributeFromFeePool(suite.ctx, suite.communityPoolAmt, suite.addresses[0]) // Add a vote to make the proposal pass - res = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[1], proposalID)) + _, err = suite.handler(suite.ctx, types.NewMsgVote(suite.addresses[1], proposalID)) - suite.True(res.IsOK()) + suite.NoError(err) // Check the proposal was not enacted suite.Equal(recipientCoins, suite.app.GetBankKeeper().GetCoins(suite.ctx, recipient)) // Check proposal and votes are gone diff --git a/x/committee/integration_test.go b/x/committee/integration_test.go index a26d7300..daaf4d8f 100644 --- a/x/committee/integration_test.go +++ b/x/committee/integration_test.go @@ -24,9 +24,9 @@ var _ types.PubProposal = UnregisteredPubProposal{} // UnregisteredPubProposal is a pubproposal type that is not registered on the amino codec. type UnregisteredPubProposal struct{} -func (UnregisteredPubProposal) GetTitle() string { return "unregistered" } -func (UnregisteredPubProposal) GetDescription() string { return "unregistered" } -func (UnregisteredPubProposal) ProposalRoute() string { return "unregistered" } -func (UnregisteredPubProposal) ProposalType() string { return "unregistered" } -func (UnregisteredPubProposal) ValidateBasic() sdk.Error { return nil } -func (UnregisteredPubProposal) String() string { return "unregistered" } +func (UnregisteredPubProposal) GetTitle() string { return "unregistered" } +func (UnregisteredPubProposal) GetDescription() string { return "unregistered" } +func (UnregisteredPubProposal) ProposalRoute() string { return "unregistered" } +func (UnregisteredPubProposal) ProposalType() string { return "unregistered" } +func (UnregisteredPubProposal) ValidateBasic() error { return nil } +func (UnregisteredPubProposal) String() string { return "unregistered" } diff --git a/x/committee/keeper/keeper.go b/x/committee/keeper/keeper.go index 1ad4815a..e6b3d9c8 100644 --- a/x/committee/keeper/keeper.go +++ b/x/committee/keeper/keeper.go @@ -6,30 +6,29 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/kava-labs/kava/x/committee/types" ) type Keeper struct { - cdc *codec.Codec - storeKey sdk.StoreKey - codespace sdk.CodespaceType + cdc *codec.Codec + storeKey sdk.StoreKey // Proposal router router govtypes.Router } -func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, router govtypes.Router, codespace sdk.CodespaceType) 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. // So the gov router must be sealed so no handlers can be added or removed after the keeper is created. router.Seal() return Keeper{ - cdc: cdc, - storeKey: storeKey, - codespace: codespace, - router: router, + cdc: cdc, + storeKey: storeKey, + router: router, } } @@ -99,17 +98,17 @@ func (k Keeper) SetNextProposalID(ctx sdk.Context, id uint64) { } // GetNextProposalID reads the next available global ID from store -func (k Keeper) GetNextProposalID(ctx sdk.Context) (uint64, sdk.Error) { +func (k Keeper) GetNextProposalID(ctx sdk.Context) (uint64, error) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.NextProposalIDKey) if bz == nil { - return 0, types.ErrInvalidGenesis(k.codespace, "next proposal ID not set at genesis") + return 0, sdkerrors.Wrap(types.ErrInvalidGenesis, "next proposal ID not set at genesis") } return types.Uint64FromBytes(bz), nil } // IncrementNextProposalID increments the next proposal ID in the store by 1. -func (k Keeper) IncrementNextProposalID(ctx sdk.Context) sdk.Error { +func (k Keeper) IncrementNextProposalID(ctx sdk.Context) error { id, err := k.GetNextProposalID(ctx) if err != nil { return err @@ -119,7 +118,7 @@ func (k Keeper) IncrementNextProposalID(ctx sdk.Context) sdk.Error { } // StoreNewProposal stores a proposal, adding a new ID -func (k Keeper) StoreNewProposal(ctx sdk.Context, pubProposal types.PubProposal, committeeID uint64, deadline time.Time) (uint64, sdk.Error) { +func (k Keeper) StoreNewProposal(ctx sdk.Context, pubProposal types.PubProposal, committeeID uint64, deadline time.Time) (uint64, error) { newProposalID, err := k.GetNextProposalID(ctx) if err != nil { return 0, err diff --git a/x/committee/keeper/proposal.go b/x/committee/keeper/proposal.go index f2db48c5..47fbd8b4 100644 --- a/x/committee/keeper/proposal.go +++ b/x/committee/keeper/proposal.go @@ -4,24 +4,25 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/kava-labs/kava/x/committee/types" ) // SubmitProposal adds a proposal to a committee so that it can be voted on. -func (k Keeper) SubmitProposal(ctx sdk.Context, proposer sdk.AccAddress, committeeID uint64, pubProposal types.PubProposal) (uint64, sdk.Error) { +func (k Keeper) SubmitProposal(ctx sdk.Context, proposer sdk.AccAddress, committeeID uint64, pubProposal types.PubProposal) (uint64, error) { // Limit proposals to only be submitted by committee members com, found := k.GetCommittee(ctx, committeeID) if !found { - return 0, types.ErrUnknownCommittee(k.codespace, committeeID) + return 0, sdkerrors.Wrapf(types.ErrUnknownCommittee, "%d", committeeID) } if !com.HasMember(proposer) { - return 0, sdk.ErrUnauthorized("proposer not member of committee") + return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "proposer not member of committee") } // Check committee has permissions to enact proposal. if !com.HasPermissionsFor(pubProposal) { - return 0, sdk.ErrUnauthorized("committee does not have permissions to enact proposal") + return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "committee does not have permissions to enact proposal") } // Check proposal is valid @@ -47,21 +48,22 @@ func (k Keeper) SubmitProposal(ctx sdk.Context, proposer sdk.AccAddress, committ } // AddVote submits a vote on a proposal. -func (k Keeper) AddVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress) sdk.Error { +func (k Keeper) AddVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress) error { // Validate pr, found := k.GetProposal(ctx, proposalID) if !found { - return types.ErrUnknownProposal(k.codespace, proposalID) + return sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) } if pr.HasExpiredBy(ctx.BlockTime()) { - return types.ErrProposalExpired(k.codespace, ctx.BlockTime(), pr.Deadline) + return sdkerrors.Wrapf(types.ErrProposalExpired, "%s ≥ %s", ctx.BlockTime(), pr.Deadline) + } com, found := k.GetCommittee(ctx, pr.CommitteeID) if !found { - return types.ErrUnknownCommittee(k.codespace, pr.CommitteeID) + return sdkerrors.Wrapf(types.ErrUnknownCommittee, "%d", pr.CommitteeID) } if !com.HasMember(voter) { - return sdk.ErrUnauthorized("voter must be a member of committee") + return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "voter must be a member of committee") } // Store vote, overwriting any prior vote @@ -78,14 +80,14 @@ func (k Keeper) AddVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress } // GetProposalResult calculates if a proposal currently has enough votes to pass. -func (k Keeper) GetProposalResult(ctx sdk.Context, proposalID uint64) (bool, sdk.Error) { +func (k Keeper) GetProposalResult(ctx sdk.Context, proposalID uint64) (bool, error) { pr, found := k.GetProposal(ctx, proposalID) if !found { - return false, types.ErrUnknownProposal(k.codespace, proposalID) + return false, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) } com, found := k.GetCommittee(ctx, pr.CommitteeID) if !found { - return false, types.ErrUnknownCommittee(k.codespace, pr.CommitteeID) + return false, sdkerrors.Wrapf(types.ErrUnknownCommittee, "%d", pr.CommitteeID) } numVotes := k.TallyVotes(ctx, proposalID) @@ -104,10 +106,10 @@ func (k Keeper) TallyVotes(ctx sdk.Context, proposalID uint64) int64 { } // EnactProposal makes the changes proposed in a proposal. -func (k Keeper) EnactProposal(ctx sdk.Context, proposalID uint64) sdk.Error { +func (k Keeper) EnactProposal(ctx sdk.Context, proposalID uint64) error { pr, found := k.GetProposal(ctx, proposalID) if !found { - return types.ErrUnknownProposal(k.codespace, proposalID) + return sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) } if err := k.ValidatePubProposal(ctx, pr.PubProposal); err != nil { @@ -144,16 +146,16 @@ func (k Keeper) CloseExpiredProposals(ctx sdk.Context) { } // ValidatePubProposal checks if a pubproposal is valid. -func (k Keeper) ValidatePubProposal(ctx sdk.Context, pubProposal types.PubProposal) (returnErr sdk.Error) { +func (k Keeper) ValidatePubProposal(ctx sdk.Context, pubProposal types.PubProposal) (returnErr error) { if pubProposal == nil { - return types.ErrInvalidPubProposal(k.codespace, "pub proposal cannot be nil") + return sdkerrors.Wrap(types.ErrInvalidPubProposal, "pub proposal cannot be nil") } if err := pubProposal.ValidateBasic(); err != nil { return err } if !k.router.HasRoute(pubProposal.ProposalRoute()) { - return types.ErrNoProposalHandlerExists(k.codespace, pubProposal) + return sdkerrors.Wrapf(types.ErrNoProposalHandlerExists, "%T", pubProposal) } // Run the proposal's changes through the associated handler using a cached version of state to ensure changes are not permanent. @@ -166,7 +168,7 @@ func (k Keeper) ValidatePubProposal(ctx sdk.Context, pubProposal types.PubPropos // reference: https://stackoverflow.com/questions/33167282/how-to-return-a-value-in-a-go-function-that-panics?noredirect=1&lq=1 defer func() { if r := recover(); r != nil { - returnErr = types.ErrInvalidPubProposal(k.codespace, fmt.Sprintf("proposal handler panicked: %s", r)) + returnErr = sdkerrors.Wrapf(types.ErrInvalidPubProposal, "proposal handler panicked: %s", r) } }() diff --git a/x/committee/keeper/querier.go b/x/committee/keeper/querier.go index a1a1a002..6e33c7c1 100644 --- a/x/committee/keeper/querier.go +++ b/x/committee/keeper/querier.go @@ -1,10 +1,9 @@ package keeper import ( - "fmt" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" abci "github.com/tendermint/tendermint/abci/types" "github.com/kava-labs/kava/x/committee/types" @@ -12,7 +11,7 @@ import ( // NewQuerier creates a new gov Querier instance func NewQuerier(keeper Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryCommittees: @@ -31,7 +30,7 @@ func NewQuerier(keeper Keeper) sdk.Querier { return queryTally(ctx, path[1:], req, keeper) default: - return nil, sdk.ErrUnknownRequest(fmt.Sprintf("unknown %s query endpoint", types.ModuleName)) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName) } } } @@ -40,32 +39,32 @@ func NewQuerier(keeper Keeper) sdk.Querier { // Committees // ------------------------------------------ -func queryCommittees(ctx sdk.Context, path []string, _ abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryCommittees(ctx sdk.Context, path []string, _ abci.RequestQuery, keeper Keeper) ([]byte, error) { committees := keeper.GetCommittees(ctx) bz, err := codec.MarshalJSONIndent(keeper.cdc, committees) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } -func queryCommittee(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryCommittee(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryCommitteeParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } committee, found := keeper.GetCommittee(ctx, params.CommitteeID) if !found { - return nil, types.ErrUnknownCommittee(types.DefaultCodespace, params.CommitteeID) + return nil, sdkerrors.Wrapf(types.ErrUnknownCommittee, "%d", params.CommitteeID) } bz, err := codec.MarshalJSONIndent(keeper.cdc, committee) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } @@ -74,37 +73,37 @@ func queryCommittee(ctx sdk.Context, path []string, req abci.RequestQuery, keepe // Proposals // ------------------------------------------ -func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryCommitteeParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } proposals := keeper.GetProposalsByCommittee(ctx, params.CommitteeID) bz, err := codec.MarshalJSONIndent(keeper.cdc, proposals) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } -func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } proposal, found := keeper.GetProposal(ctx, params.ProposalID) if !found { - return nil, types.ErrUnknownProposal(types.DefaultCodespace, params.ProposalID) + return nil, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", params.ProposalID) } bz, err := codec.MarshalJSONIndent(keeper.cdc, proposal) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } @@ -113,38 +112,38 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper // Votes // ------------------------------------------ -func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } votes := keeper.GetVotesByProposal(ctx, params.ProposalID) bz, err := codec.MarshalJSONIndent(keeper.cdc, votes) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } -func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryVoteParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } vote, found := keeper.GetVote(ctx, params.ProposalID, params.Voter) if !found { - return nil, types.ErrUnknownVote(types.DefaultCodespace, params.ProposalID, params.Voter) + return nil, sdkerrors.Wrapf(types.ErrUnknownVote, "proposal id: %d, voter: %s", params.ProposalID, params.Voter) } bz, err := codec.MarshalJSONIndent(keeper.cdc, vote) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } @@ -153,22 +152,22 @@ func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Kee // Tally // ------------------------------------------ -func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { +func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, error) { var params types.QueryProposalParams err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if err != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } _, found := keeper.GetProposal(ctx, params.ProposalID) if !found { - return nil, types.ErrUnknownProposal(types.DefaultCodespace, params.ProposalID) + return nil, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", params.ProposalID) } numVotes := keeper.TallyVotes(ctx, params.ProposalID) bz, err := codec.MarshalJSONIndent(keeper.cdc, numVotes) if err != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } diff --git a/x/committee/module.go b/x/committee/module.go index f39e8c44..1423eff7 100644 --- a/x/committee/module.go +++ b/x/committee/module.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth" sim "github.com/cosmos/cosmos-sdk/x/simulation" abci "github.com/tendermint/tendermint/abci/types" @@ -22,7 +23,7 @@ import ( var ( _ module.AppModule = AppModule{} _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic app module basics object @@ -70,39 +71,20 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { //____________________________________________________________________________ -// AppModuleSimulation defines the module simulation functions used by the module. -type AppModuleSimulation struct{} - -// RegisterStoreDecoder registers a decoder for the module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - sdr[StoreKey] = simulation.DecodeStore -} - -// GenerateGenesisState creates a randomized GenState of the module -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { - simulation.RandomizedGenState(simState) -} - -// RandomizedParams creates randomized param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return simulation.ParamChanges(r) -} - -//____________________________________________________________________________ - // AppModule app module type type AppModule struct { AppModuleBasic - AppModuleSimulation - keeper Keeper + keeper Keeper + accountKeeper auth.AccountKeeper } // NewAppModule creates a new AppModule object -func NewAppModule(keeper Keeper) AppModule { +func NewAppModule(keeper Keeper, accountKeeper auth.AccountKeeper) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, keeper: keeper, + accountKeeper: accountKeeper, } } @@ -116,7 +98,7 @@ func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // Route module message route name func (AppModule) Route() string { - return ModuleName + return RouterKey } // NewHandler module handler @@ -126,7 +108,7 @@ func (am AppModule) NewHandler() sdk.Handler { // QuerierRoute module querier route name func (AppModule) QuerierRoute() string { - return ModuleName + return QuerierRoute } // NewQuerierHandler module querier @@ -158,3 +140,30 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } + +//____________________________________________________________________________ + +// GenerateGenesisState creates a randomized GenState for the module +func (AppModuleBasic) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) +} + +// TODO +func (AppModuleBasic) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { + return nil +} + +// RandomizedParams returns functions that generate params for the module. +func (AppModuleBasic) RandomizedParams(r *rand.Rand) []sim.ParamChange { + return nil +} + +// RegisterStoreDecoder registers a decoder for the module's types +func (AppModuleBasic) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { + sdr[StoreKey] = simulation.DecodeStore +} + +// WeightedOperations returns the all the auction module operations with their respective weights. +func (am AppModule) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { + return nil // TODO simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.accountKeeper, am.keeper) +} diff --git a/x/committee/proposal_handler.go b/x/committee/proposal_handler.go index da5a049e..bae3d4ff 100644 --- a/x/committee/proposal_handler.go +++ b/x/committee/proposal_handler.go @@ -1,14 +1,13 @@ package committee import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) func NewProposalHandler(k Keeper) govtypes.Handler { - return func(ctx sdk.Context, content govtypes.Content) sdk.Error { + return func(ctx sdk.Context, content govtypes.Content) error { switch c := content.(type) { case CommitteeChangeProposal: return handleCommitteeChangeProposal(ctx, k, c) @@ -16,15 +15,14 @@ func NewProposalHandler(k Keeper) govtypes.Handler { return handleCommitteeDeleteProposal(ctx, k, c) default: - errMsg := fmt.Sprintf("unrecognized %s proposal content type: %T", ModuleName, c) - return sdk.ErrUnknownRequest(errMsg) + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s proposal content type: %T", ModuleName, c) } } } -func handleCommitteeChangeProposal(ctx sdk.Context, k Keeper, committeeProposal CommitteeChangeProposal) sdk.Error { +func handleCommitteeChangeProposal(ctx sdk.Context, k Keeper, committeeProposal CommitteeChangeProposal) error { if err := committeeProposal.ValidateBasic(); err != nil { - return ErrInvalidCommittee(DefaultCodespace, err.Error()) + return sdkerrors.Wrap(ErrInvalidPubProposal, err.Error()) } // Remove all committee's ongoing proposals @@ -41,9 +39,9 @@ func handleCommitteeChangeProposal(ctx sdk.Context, k Keeper, committeeProposal return nil } -func handleCommitteeDeleteProposal(ctx sdk.Context, k Keeper, committeeProposal CommitteeDeleteProposal) sdk.Error { +func handleCommitteeDeleteProposal(ctx sdk.Context, k Keeper, committeeProposal CommitteeDeleteProposal) error { if err := committeeProposal.ValidateBasic(); err != nil { - return ErrInvalidPubProposal(DefaultCodespace, err.Error()) + return sdkerrors.Wrap(ErrInvalidPubProposal, err.Error()) } // Remove all committee's ongoing proposals diff --git a/x/committee/simulation/decoder.go b/x/committee/simulation/decoder.go index 2cdd439b..bcbba73f 100644 --- a/x/committee/simulation/decoder.go +++ b/x/committee/simulation/decoder.go @@ -2,11 +2,11 @@ package simulation import ( "github.com/cosmos/cosmos-sdk/codec" - cmn "github.com/tendermint/tendermint/libs/common" + "github.com/tendermint/tendermint/libs/kv" ) // DecodeStore unmarshals the KVPair's Value to the corresponding module type -func DecodeStore(cdc *codec.Codec, kvA, kvB cmn.KVPair) string { +func DecodeStore(cdc *codec.Codec, kvA, kvB kv.Pair) string { // TODO implement this return "" } diff --git a/x/committee/simulation/genesis.go b/x/committee/simulation/genesis.go index 5f11ea53..22a25439 100644 --- a/x/committee/simulation/genesis.go +++ b/x/committee/simulation/genesis.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/kava-labs/kava/x/auction/types" + "github.com/kava-labs/kava/x/committee/types" ) // RandomizedGenState generates a random GenesisState for the module diff --git a/x/committee/types/codec.go b/x/committee/types/codec.go index bdac0489..5c246fc0 100644 --- a/x/committee/types/codec.go +++ b/x/committee/types/codec.go @@ -24,7 +24,6 @@ func RegisterModuleCodec(cdc *codec.Codec) { cdc.RegisterConcrete(distribution.CommunityPoolSpendProposal{}, "cosmos-sdk/CommunityPoolSpendProposal", nil) cdc.RegisterConcrete(params.ParameterChangeProposal{}, "cosmos-sdk/ParameterChangeProposal", nil) cdc.RegisterConcrete(gov.TextProposal{}, "cosmos-sdk/TextProposal", nil) - cdc.RegisterConcrete(gov.SoftwareUpgradeProposal{}, "cosmos-sdk/SoftwareUpgradeProposal", nil) RegisterAppCodec(cdc) } @@ -43,6 +42,7 @@ func RegisterAppCodec(cdc *codec.Codec) { cdc.RegisterInterface((*Permission)(nil), nil) cdc.RegisterConcrete(GodPermission{}, "kava/GodPermission", nil) cdc.RegisterConcrete(ParamChangePermission{}, "kava/ParamChangePermission", nil) + cdc.RegisterConcrete(TextPermission{}, "kava/TextPermission", nil) // Msgs cdc.RegisterConcrete(MsgSubmitProposal{}, "kava/MsgSubmitProposal", nil) diff --git a/x/committee/types/committee_test.go b/x/committee/types/committee_test.go index 1f7ec077..434b2049 100644 --- a/x/committee/types/committee_test.go +++ b/x/committee/types/committee_test.go @@ -37,7 +37,6 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", }, }}}, pubProposal: params.NewParameterChangeProposal( @@ -47,8 +46,8 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, }, ), @@ -62,7 +61,6 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", }, }}, TextPermission{}, @@ -78,7 +76,6 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", }, }}, GodPermission{}, @@ -90,8 +87,8 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "CollateralParams", - Subkey: "", - Value: `[]`, + + Value: `[]`, }, }, ), @@ -107,8 +104,8 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "CollateralParams", - Subkey: "", - Value: `[]`, + + Value: `[]`, }, }, ), @@ -123,7 +120,6 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", }, }}, ParamChangePermission{ @@ -131,7 +127,6 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtParams", - Subkey: "", }, }}, }, @@ -142,14 +137,14 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, { Subspace: "cdp", Key: "DebtParams", - Subkey: "", - Value: `[]`, + + Value: `[]`, }, }, ), @@ -163,7 +158,6 @@ func (suite *TypesTestSuite) TestCommittee_HasPermissionsFor() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", }, }}, }, diff --git a/x/committee/types/errors.go b/x/committee/types/errors.go index 0fa66126..e64766a4 100644 --- a/x/committee/types/errors.go +++ b/x/committee/types/errors.go @@ -1,50 +1,17 @@ package types import ( - "fmt" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -const ( - DefaultCodespace sdk.CodespaceType = ModuleName - - CodeProposalExpired sdk.CodeType = 1 - CodeUnknownItem sdk.CodeType = 2 - CodeInvalidGenesis sdk.CodeType = 3 - CodeInvalidProposal sdk.CodeType = 4 - CodeInvalidCommittee sdk.CodeType = 5 +// TODO nums ok? +var ( + ErrUnknownCommittee = sdkerrors.Register(ModuleName, 2, "committee not found") + ErrInvalidCommittee = sdkerrors.Register(ModuleName, 3, "invalid committee") + ErrUnknownProposal = sdkerrors.Register(ModuleName, 4, "proposal not found") + ErrProposalExpired = sdkerrors.Register(ModuleName, 5, "proposal expired") + ErrInvalidPubProposal = sdkerrors.Register(ModuleName, 6, "invalid pubproposal") + ErrUnknownVote = sdkerrors.Register(ModuleName, 7, "vote not found") + ErrInvalidGenesis = sdkerrors.Register(ModuleName, 8, "invalid genesis") + ErrNoProposalHandlerExists = sdkerrors.Register(ModuleName, 9, "pubproposal has no corresponding handler") ) - -func ErrUnknownCommittee(codespace sdk.CodespaceType, id uint64) sdk.Error { - return sdk.NewError(codespace, CodeUnknownItem, fmt.Sprintf("committee with id '%d' not found", id)) -} - -func ErrInvalidCommittee(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidCommittee, msg) -} - -func ErrUnknownProposal(codespace sdk.CodespaceType, id uint64) sdk.Error { - return sdk.NewError(codespace, CodeUnknownItem, fmt.Sprintf("proposal with id '%d' not found", id)) -} - -func ErrProposalExpired(codespace sdk.CodespaceType, blockTime, expiry time.Time) sdk.Error { - return sdk.NewError(codespace, CodeProposalExpired, fmt.Sprintf("proposal expired at %s, current blocktime %s", expiry, blockTime)) -} - -func ErrInvalidPubProposal(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidProposal, msg) -} - -func ErrUnknownVote(codespace sdk.CodespaceType, proposalID uint64, voter sdk.AccAddress) sdk.Error { - return sdk.NewError(codespace, CodeUnknownItem, fmt.Sprintf("vote with for proposal '%d' and voter %s not found", proposalID, voter)) -} - -func ErrInvalidGenesis(codespace sdk.CodespaceType, msg string) sdk.Error { - return sdk.NewError(codespace, CodeInvalidGenesis, msg) -} - -func ErrNoProposalHandlerExists(codespace sdk.CodespaceType, content interface{}) sdk.Error { - return sdk.NewError(codespace, CodeUnknownItem, fmt.Sprintf("'%T' does not have a corresponding handler", content)) -} diff --git a/x/committee/types/msg.go b/x/committee/types/msg.go index 5e2b138b..50ac64f6 100644 --- a/x/committee/types/msg.go +++ b/x/committee/types/msg.go @@ -2,6 +2,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) const ( @@ -34,12 +35,12 @@ func (msg MsgSubmitProposal) Route() string { return RouterKey } func (msg MsgSubmitProposal) Type() string { return TypeMsgSubmitProposal } // ValidateBasic does a simple validation check that doesn't require access to any other information. -func (msg MsgSubmitProposal) ValidateBasic() sdk.Error { +func (msg MsgSubmitProposal) ValidateBasic() error { if msg.PubProposal == nil { - return ErrInvalidPubProposal(DefaultCodespace, "pub proposal cannot be nil") + return sdkerrors.Wrap(ErrInvalidPubProposal, "pub proposal cannot be nil") } if msg.Proposer.Empty() { - return sdk.ErrInvalidAddress(msg.Proposer.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "proposer address cannot be empty") } return msg.PubProposal.ValidateBasic() @@ -74,9 +75,9 @@ func (msg MsgVote) Route() string { return RouterKey } func (msg MsgVote) Type() string { return TypeMsgVote } // ValidateBasic does a simple validation check that doesn't require access to any other information. -func (msg MsgVote) ValidateBasic() sdk.Error { +func (msg MsgVote) ValidateBasic() error { if msg.Voter.Empty() { - return sdk.ErrInvalidAddress(msg.Voter.String()) + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "voter address cannot be empty") } return nil } diff --git a/x/committee/types/permissions.go b/x/committee/types/permissions.go index 6608d9bd..1b33a46e 100644 --- a/x/committee/types/permissions.go +++ b/x/committee/types/permissions.go @@ -76,13 +76,12 @@ func (perm ParamChangePermission) MarshalYAML() (interface{}, error) { type AllowedParam struct { Subspace string `json:"subspace" yaml:"subspace"` Key string `json:"key" yaml:"key"` - Subkey string `json:"subkey,omitempty" yaml:"subkey,omitempty"` } type AllowedParams []AllowedParam func (allowed AllowedParams) Contains(paramChange params.ParamChange) bool { for _, p := range allowed { - if paramChange.Subspace == p.Subspace && paramChange.Key == p.Key && paramChange.Subkey == p.Subkey { + if paramChange.Subspace == p.Subspace && paramChange.Key == p.Key { return true } } diff --git a/x/committee/types/permissions_test.go b/x/committee/types/permissions_test.go index 9794d10a..96a2fa25 100644 --- a/x/committee/types/permissions_test.go +++ b/x/committee/types/permissions_test.go @@ -19,22 +19,18 @@ func (suite *PermissionsTestSuite) SetupTest() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", }, { Subspace: "cdp", Key: "SurplusThreshold", - Subkey: "", }, { Subspace: "cdp", Key: "CollateralParams", - Subkey: "", }, { Subspace: "auction", Key: "BidDuration", - Subkey: "", }, } } @@ -56,8 +52,8 @@ func (suite *PermissionsTestSuite) TestParamChangePermission_Allows() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, }, ), @@ -73,14 +69,14 @@ func (suite *PermissionsTestSuite) TestParamChangePermission_Allows() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, { Subspace: "cdp", Key: "CollateralParams", - Subkey: "", - Value: `[]`, + + Value: `[]`, }, }, ), @@ -96,8 +92,8 @@ func (suite *PermissionsTestSuite) TestParamChangePermission_Allows() { { Subspace: "cdp", Key: "GlobalDebtLimit", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000000"}`, }, }, ), @@ -113,8 +109,8 @@ func (suite *PermissionsTestSuite) TestParamChangePermission_Allows() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `[{"denom": "usdx", "amount": "1000000"}]`, + + Value: `[{"denom": "usdx", "amount": "1000000"}]`, }, }, ), @@ -160,8 +156,8 @@ func (suite *PermissionsTestSuite) TestAllowedParams_Contains() { testParam: params.ParamChange{ Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, expectContained: true, }, @@ -171,8 +167,8 @@ func (suite *PermissionsTestSuite) TestAllowedParams_Contains() { testParam: params.ParamChange{ Subspace: "", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, expectContained: false, }, @@ -182,8 +178,8 @@ func (suite *PermissionsTestSuite) TestAllowedParams_Contains() { testParam: params.ParamChange{ Subspace: "cdp", Key: "", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, expectContained: false, }, @@ -193,8 +189,8 @@ func (suite *PermissionsTestSuite) TestAllowedParams_Contains() { testParam: params.ParamChange{ Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, expectContained: false, }, @@ -204,8 +200,8 @@ func (suite *PermissionsTestSuite) TestAllowedParams_Contains() { testParam: params.ParamChange{ Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", - Value: `{"denom": "usdx", "amount": "1000000"}`, + + Value: `{"denom": "usdx", "amount": "1000000"}`, }, expectContained: false, }, @@ -256,13 +252,11 @@ func (suite *PermissionsTestSuite) TestTextPermission_Allows() { { Subspace: "cdp", Key: "DebtThreshold", - Subkey: "", Value: `{"denom": "usdx", "amount": "1000000"}`, }, { Subspace: "cdp", Key: "CollateralParams", - Subkey: "", Value: `[]`, }, }, diff --git a/x/committee/types/proposal.go b/x/committee/types/proposal.go index 45bfe0a4..95f073fa 100644 --- a/x/committee/types/proposal.go +++ b/x/committee/types/proposal.go @@ -3,7 +3,7 @@ package types import ( "gopkg.in/yaml.v2" - sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -48,12 +48,12 @@ func (ccp CommitteeChangeProposal) ProposalRoute() string { return RouterKey } func (ccp CommitteeChangeProposal) ProposalType() string { return ProposalTypeCommitteeChange } // ValidateBasic runs basic stateless validity checks -func (ccp CommitteeChangeProposal) ValidateBasic() sdk.Error { - if err := govtypes.ValidateAbstract(DefaultCodespace, ccp); err != nil { +func (ccp CommitteeChangeProposal) ValidateBasic() error { + if err := govtypes.ValidateAbstract(ccp); err != nil { return err } if err := ccp.NewCommittee.Validate(); err != nil { - return ErrInvalidCommittee(DefaultCodespace, err.Error()) + return sdkerrors.Wrap(ErrInvalidCommittee, err.Error()) } return nil } @@ -100,11 +100,8 @@ func (cdp CommitteeDeleteProposal) ProposalRoute() string { return RouterKey } func (cdp CommitteeDeleteProposal) ProposalType() string { return ProposalTypeCommitteeDelete } // ValidateBasic runs basic stateless validity checks -func (cdp CommitteeDeleteProposal) ValidateBasic() sdk.Error { - if err := govtypes.ValidateAbstract(DefaultCodespace, cdp); err != nil { - return err - } - return nil +func (cdp CommitteeDeleteProposal) ValidateBasic() error { + return govtypes.ValidateAbstract(cdp) } // String implements the Stringer interface.