Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: deposit to validator rewards pool #14322

Merged
merged 19 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,301 changes: 1,212 additions & 89 deletions api/cosmos/distribution/v1beta1/tx.pulsar.go

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions api/cosmos/distribution/v1beta1/tx_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 46 additions & 9 deletions proto/cosmos/distribution/v1beta1/tx.proto
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
syntax = "proto3";
package cosmos.distribution.v1beta1;

option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types";
option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types";
option (gogoproto.equal_all) = true;

import "gogoproto/gogo.proto";
Expand All @@ -17,19 +17,23 @@ service Msg {

// SetWithdrawAddress defines a method to change the withdraw address
// for a delegator (or validator self-delegation).
rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse);
rpc SetWithdrawAddress(MsgSetWithdrawAddress)
returns (MsgSetWithdrawAddressResponse);

// WithdrawDelegatorReward defines a method to withdraw rewards of delegator
// from a single validator.
rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse);
rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward)
returns (MsgWithdrawDelegatorRewardResponse);

// WithdrawValidatorCommission defines a method to withdraw the
// full commission to the validator address.
rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse);
rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission)
returns (MsgWithdrawValidatorCommissionResponse);

// FundCommunityPool defines a method to allow an account to directly
// fund the community pool.
rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse);
rpc FundCommunityPool(MsgFundCommunityPool)
returns (MsgFundCommunityPoolResponse);

// UpdateParams defines a governance operation for updating the x/distribution
// module parameters. The authority is defined in the keeper.
Expand All @@ -43,7 +47,15 @@ service Msg {
// keeper.
//
// Since: cosmos-sdk 0.47
rpc CommunityPoolSpend(MsgCommunityPoolSpend) returns (MsgCommunityPoolSpendResponse);
rpc CommunityPoolSpend(MsgCommunityPoolSpend)
returns (MsgCommunityPoolSpendResponse);

// DepositValidatorRewardsPool defines a method to provide additional rewards
// to delegators to a specific validator.
//
// Since: cosmos-sdk 0.48
rpc DepositValidatorRewardsPool(MsgDepositValidatorRewardsPool)
returns (MsgDepositValidatorRewardsPoolResponse);
}

// MsgSetWithdrawAddress sets the withdraw address for
Expand Down Expand Up @@ -143,7 +155,8 @@ message MsgUpdateParams {
// params defines the x/distribution parameters to update.
//
// NOTE: All parameters must be supplied.
Params params = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
Params params = 2
[(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// MsgUpdateParamsResponse defines the response structure for executing a
Expand All @@ -162,8 +175,8 @@ message MsgCommunityPoolSpend {
option (amino.name) = "cosmos-sdk/distr/MsgCommunityPoolSpend";

// authority is the address of the governance account.
string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string recipient = 2;
string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string recipient = 2;
repeated cosmos.base.v1beta1.Coin amount = 3 [
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true,
Expand All @@ -176,3 +189,27 @@ message MsgCommunityPoolSpend {
//
// Since: cosmos-sdk 0.47
message MsgCommunityPoolSpendResponse {}

// DepositValidatorRewardsPool defines the request structure to provide
// additional rewards to delegators from a specific validator.
//
// Since: cosmos-sdk 0.48
message MsgDepositValidatorRewardsPool {
option (cosmos.msg.v1.signer) = "authority";

option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

// MsgDepositValidatorRewardsPoolResponse defines the response to executing a
// MsgDepositValidatorRewardsPool message.
//
// Since: cosmos-sdk 0.48
message MsgDepositValidatorRewardsPoolResponse {}
40 changes: 40 additions & 0 deletions x/distribution/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func NewTxCmd() *cobra.Command {
NewWithdrawAllRewardsCmd(),
NewSetWithdrawAddrCmd(),
NewFundCommunityPoolCmd(),
NewDepositValidatorRewardsPoolCmd(),
)

return distTxCmd
Expand Down Expand Up @@ -254,3 +255,42 @@ $ %s tx distribution fund-community-pool 100uatom --from mykey

return cmd
}

// NewDepositValidatorRewardsPoolCmd returns a CLI command handler for creating
// a MsgDepositValidatorRewardsPool transaction.
func NewDepositValidatorRewardsPoolCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "fund-validator-rewards-pool [val_addr] [amount]",
Args: cobra.ExactArgs(2),
Short: "Fund the validator rewards pool with the specified amount",
Example: fmt.Sprintf(
"%s tx distribution fund-validator-rewards-pool cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp 100uatom --from mykey",
version.AppName,
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

depositorAddr := clientCtx.GetFromAddress()

valAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}

amount, err := sdk.ParseCoinsNormalized(args[1])
if err != nil {
return err
}

msg := types.NewMsgDepositValidatorRewardsPool(depositorAddr, valAddr, amount)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}
36 changes: 36 additions & 0 deletions x/distribution/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,39 @@ func (k msgServer) CommunityPoolSpend(goCtx context.Context, req *types.MsgCommu

return &types.MsgCommunityPoolSpendResponse{}, nil
}

func (k msgServer) DepositValidatorRewardsPool(goCtx context.Context, req *types.MsgDepositValidatorRewardsPool) (*types.MsgDepositValidatorRewardsPoolResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

authority, err := sdk.AccAddressFromBech32(req.Authority)
if err != nil {
return nil, err
}

// deposit coins from sender's account to the distribution module
if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, authority, types.ModuleName, req.Amount); err != nil {
return nil, err
}

valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddress)
if err != nil {
return nil, err
}

validator := k.stakingKeeper.Validator(ctx, valAddr)

// Allocate tokens from the distribution module to the validator, which are
// then distributed to the validator's delegators.
reward := sdk.NewDecCoinsFromCoins(req.Amount...)
k.AllocateTokensToValidator(ctx, validator, reward)

logger := k.Logger(ctx)
logger.Info(
"transferred from rewards to validator rewards pool",
"authority", req.Authority,
"amount", req.Amount.String(),
"validator", req.ValidatorAddress,
)

return &types.MsgDepositValidatorRewardsPoolResponse{}, nil
}
5 changes: 4 additions & 1 deletion x/distribution/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
legacy.RegisterAminoMsg(cdc, &MsgFundCommunityPool{}, "cosmos-sdk/MsgFundCommunityPool")
legacy.RegisterAminoMsg(cdc, &MsgUpdateParams{}, "cosmos-sdk/distribution/MsgUpdateParams")
legacy.RegisterAminoMsg(cdc, &MsgCommunityPoolSpend{}, "cosmos-sdk/distr/MsgCommunityPoolSpend")
legacy.RegisterAminoMsg(cdc, &MsgDepositValidatorRewardsPool{}, "cosmos-sdk/distr/MsgDepositValRewards")

cdc.RegisterConcrete(Params{}, "cosmos-sdk/x/distribution/Params", nil)
}
Expand All @@ -36,11 +37,13 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgFundCommunityPool{},
&MsgUpdateParams{},
&MsgCommunityPoolSpend{},
&MsgDepositValidatorRewardsPool{},
)

registry.RegisterImplementations(
(*govtypes.Content)(nil),
&CommunityPoolSpendProposal{})
&CommunityPoolSpendProposal{},
)

msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
Expand Down
41 changes: 41 additions & 0 deletions x/distribution/types/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const (
TypeMsgFundCommunityPool = "fund_community_pool"
TypeMsgUpdateParams = "update_params"
TypeMsgCommunityPoolSpend = "community_pool_spend"
TypeMsgDepositValidatorRewardsPool = "deposit_validator_rewards_pool"
)

// Verify interface at compile time
Expand All @@ -22,6 +23,7 @@ var (
_ sdk.Msg = (*MsgWithdrawValidatorCommission)(nil)
_ sdk.Msg = (*MsgUpdateParams)(nil)
_ sdk.Msg = (*MsgCommunityPoolSpend)(nil)
_ sdk.Msg = (*MsgDepositValidatorRewardsPool)(nil)
)

func NewMsgSetWithdrawAddress(delAddr, withdrawAddr sdk.AccAddress) *MsgSetWithdrawAddress {
Expand Down Expand Up @@ -217,3 +219,42 @@ func (msg MsgCommunityPoolSpend) ValidateBasic() error {

return msg.Amount.Validate()
}

// NewMsgDepositValidatorRewardsPool returns a new MsgDepositValidatorRewardsPool
// with a sender and a funding amount.
func NewMsgDepositValidatorRewardsPool(depositor sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coins) *MsgDepositValidatorRewardsPool {
return &MsgDepositValidatorRewardsPool{
Amount: amount,
Authority: depositor.String(),
ValidatorAddress: valAddr.String(),
}
}

// Route returns the MsgDepositValidatorRewardsPool message route.
func (msg MsgDepositValidatorRewardsPool) Route() string { return ModuleName }

// Type returns the MsgDepositValidatorRewardsPool message type.
func (msg MsgDepositValidatorRewardsPool) Type() string { return TypeMsgDepositValidatorRewardsPool }

// GetSigners returns the signer addresses that are expected to sign the result
// of GetSignBytes, which is the authority.
func (msg MsgDepositValidatorRewardsPool) GetSigners() []sdk.AccAddress {
authority, _ := sdk.AccAddressFromBech32(msg.Authority)

Check warning

Code scanning / gosec

Returned error is not propagated up the stack.

Returned error is not propagated up the stack.
return []sdk.AccAddress{authority}
}

// GetSignBytes returns the raw bytes for a MsgDepositValidatorRewardsPool message
// that the expected signer needs to sign.
func (msg MsgDepositValidatorRewardsPool) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(&msg)
return sdk.MustSortJSON(bz)
}

// ValidateBasic performs basic MsgDepositValidatorRewardsPool message validation.
func (msg MsgDepositValidatorRewardsPool) ValidateBasic() error {
if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil {
return sdkerrors.ErrInvalidAddress.Wrapf("invalid authority address: %s", err)
}

return msg.Amount.Validate()
}
Loading