diff --git a/simapp/app.go b/simapp/app.go index 53e671a1242d..ef61a4b96078 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -182,7 +182,7 @@ func NewSimApp( supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper), gov.NewAppModule(app.GovKeeper, app.SupplyKeeper), mint.NewAppModule(app.MintKeeper), - distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper), + distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper, app.BankKeeper), slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper), staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper), ) @@ -216,7 +216,7 @@ func NewSimApp( supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper), gov.NewAppModule(app.GovKeeper, app.SupplyKeeper), mint.NewAppModule(app.MintKeeper), - distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper), + distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper, app.BankKeeper), staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper), slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper), ) diff --git a/x/distribution/handler.go b/x/distribution/handler.go index ca047cec3672..21243922e6f3 100644 --- a/x/distribution/handler.go +++ b/x/distribution/handler.go @@ -4,12 +4,13 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/distribution/keeper" "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) -func NewHandler(k keeper.Keeper) sdk.Handler { +func NewHandler(k keeper.Keeper, bankKeeper bank.Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { ctx = ctx.WithEventManager(sdk.NewEventManager()) @@ -23,6 +24,9 @@ func NewHandler(k keeper.Keeper) sdk.Handler { case types.MsgWithdrawValidatorCommission: return handleMsgWithdrawValidatorCommission(ctx, msg, k) + case types.MsgDepositIntoCommunityPool: + return handleMsgDepositIntoCommunityPool(ctx, msg, k, bankKeeper) + default: errMsg := fmt.Sprintf("unrecognized distribution message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() @@ -83,6 +87,26 @@ func handleMsgWithdrawValidatorCommission(ctx sdk.Context, msg types.MsgWithdraw return sdk.Result{Events: ctx.EventManager().Events()} } +func handleMsgDepositIntoCommunityPool(ctx sdk.Context, msg types.MsgDepositIntoCommunityPool, k keeper.Keeper, bankK bank.Keeper) sdk.Result { + if _, err := bankK.SubtractCoins(ctx, msg.Depositor, msg.Amount); err != nil { + return err.Result() + } + + pool := k.GetFeePool(ctx) + pool.CommunityPool = pool.CommunityPool.Add(sdk.NewDecCoins(msg.Amount)) + k.SetFeePool(ctx, pool) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Depositor.String()), + ), + ) + + return sdk.Result{Events: ctx.EventManager().Events()} +} + func NewCommunityPoolSpendProposalHandler(k Keeper) govtypes.Handler { return func(ctx sdk.Context, content govtypes.Content) sdk.Error { switch c := content.(type) { diff --git a/x/distribution/module.go b/x/distribution/module.go index 2b42e0b68c51..669a2daa563d 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -4,6 +4,7 @@ import ( "encoding/json" "math/rand" + "github.com/cosmos/cosmos-sdk/x/bank" "github.com/gorilla/mux" "github.com/spf13/cobra" @@ -99,15 +100,17 @@ type AppModule struct { keeper Keeper supplyKeeper types.SupplyKeeper + bankKeeper bank.Keeper } // NewAppModule creates a new AppModule object -func NewAppModule(keeper Keeper, supplyKeeper types.SupplyKeeper) AppModule { +func NewAppModule(keeper Keeper, supplyKeeper types.SupplyKeeper, bankKeeper bank.Keeper) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, AppModuleSimulation: AppModuleSimulation{}, keeper: keeper, supplyKeeper: supplyKeeper, + bankKeeper: bankKeeper, } } @@ -128,7 +131,7 @@ func (AppModule) Route() string { // NewHandler returns an sdk.Handler for the distribution module. func (am AppModule) NewHandler() sdk.Handler { - return NewHandler(am.keeper) + return NewHandler(am.keeper, am.bankKeeper) } // QuerierRoute returns the distribution module's querier route name. diff --git a/x/distribution/types/msg.go b/x/distribution/types/msg.go index a5eb8422be97..8bc8b1a0dd52 100644 --- a/x/distribution/types/msg.go +++ b/x/distribution/types/msg.go @@ -116,3 +116,41 @@ func (msg MsgWithdrawValidatorCommission) ValidateBasic() sdk.Error { } return nil } + +// msg struct for delegation withdraw from a single validator +type MsgDepositIntoCommunityPool struct { + Amount sdk.Coins `json:"amount" yaml:"amount"` + Depositor sdk.AccAddress `json:"depositor" yaml:"depositor"` +} + +func NewMsgDepositIntoCommunityPool(amount sdk.Coins, depositor sdk.AccAddress) MsgDepositIntoCommunityPool { + return MsgDepositIntoCommunityPool{ + Amount: amount, + Depositor: depositor, + } +} + +func (msg MsgDepositIntoCommunityPool) Route() string { return ModuleName } +func (msg MsgDepositIntoCommunityPool) Type() string { return "deposit_into_community_pool" } + +// Return address that must sign over msg.GetSignBytes() +func (msg MsgDepositIntoCommunityPool) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Depositor} +} + +// get the bytes for the message signer to sign on +func (msg MsgDepositIntoCommunityPool) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// quick validity check +func (msg MsgDepositIntoCommunityPool) ValidateBasic() sdk.Error { + if !msg.Amount.IsValid() { + return sdk.ErrInvalidCoins(msg.Amount.String()) + } + if msg.Depositor.Empty() { + return sdk.ErrInvalidAddress(msg.Depositor.String()) + } + return nil +}