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 all commits
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
11 changes: 6 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,20 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (x/slashing, x/staking) [#14363](https://github.com/cosmos/cosmos-sdk/pull/14363) Add the infraction a validator commited type as an argument to a `SlashWithInfractionReason` keeper method.
* (x/distribution) [#14322](https://github.com/cosmos/cosmos-sdk/pull/14322) Introduce a new gRPC message handler, `DepositValidatorRewardsPool`, that allows explicit funding of a validator's reward pool.
* (x/slashing, x/staking) [#14363](https://github.com/cosmos/cosmos-sdk/pull/14363) Add the infraction a validator committed type as an argument to a `SlashWithInfractionReason` keeper method.
* (x/evidence) [#13740](https://github.com/cosmos/cosmos-sdk/pull/13740) Add new proto field `hash` of type `string` to `QueryEvidenceRequest` which helps to decode the hash properly while using query API.
* (core) [#13306](https://github.com/cosmos/cosmos-sdk/pull/13306) Add a `FormatCoins` function to in `core/coins` to format sdk Coins following the Value Renderers spec.
* (math) [#13306](https://github.com/cosmos/cosmos-sdk/pull/13306) Add `FormatInt` and `FormatDec` functiosn in `math` to format integers and decimals following the Value Renderers spec.
* (math) [#13306](https://github.com/cosmos/cosmos-sdk/pull/13306) Add `FormatInt` and `FormatDec` functions in `math` to format integers and decimals following the Value Renderers spec.
* (x/staking) [#13122](https://github.com/cosmos/cosmos-sdk/pull/13122) Add `UnbondingCanComplete` and `PutUnbondingOnHold` to `x/staking` module.
* [#13437](https://github.com/cosmos/cosmos-sdk/pull/13437) Add new flag `--modules-to-export` in `simd export` command to export only selected modules.
* [#13298](https://github.com/cosmos/cosmos-sdk/pull/13298) Add `AddGenesisAccount` helper func in x/auth module which helps adding accounts to genesis state.
* (x/authz) [#12648](https://github.com/cosmos/cosmos-sdk/pull/12648) Add an allow list, an optional list of addresses allowed to receive bank assets via authz MsgSend grant.
* (sdk.Coins) [#12627](https://github.com/cosmos/cosmos-sdk/pull/12627) Make a Denoms method on sdk.Coins.
* (sdk.Coins) [#12627](https://github.com/cosmos/cosmos-sdk/pull/12627) Make a `Denoms` method on sdk.Coins.
* (testutil) [#12973](https://github.com/cosmos/cosmos-sdk/pull/12973) Add generic `testutil.RandSliceElem` function which selects a random element from the list.
* (client) [#12936](https://github.com/cosmos/cosmos-sdk/pull/12936) Add capability to preprocess transactions before broadcasting from a higher level chain.
* (client) [#12936](https://github.com/cosmos/cosmos-sdk/pull/12936) Add capability to pre-process transactions before broadcasting from a higher level chain.
* (cli) [#13064](https://github.com/cosmos/cosmos-sdk/pull/13064) Add `debug prefixes` to list supported HRP prefixes via .
* (ledger) [#12935](https://github.com/cosmos/cosmos-sdk/pull/12935) Generalize Ledger integration to allow for different apps or keytypes that use SECP256k1.
* (ledger) [#12935](https://github.com/cosmos/cosmos-sdk/pull/12935) Generalize Ledger integration to allow for different apps or key types that use SECP256k1.
* (x/bank) [#11981](https://github.com/cosmos/cosmos-sdk/pull/11981) Create the `SetSendEnabled` endpoint for managing the bank's SendEnabled settings.
* (x/auth) [#13210](https://github.com/cosmos/cosmos-sdk/pull/13210) Add `Query/AccountInfo` endpoint for simplified access to basic account info.
* (x/consensus) [#12905](https://github.com/cosmos/cosmos-sdk/pull/12905) Create a new `x/consensus` module that is now responsible for maintaining Tendermint consensus parameters instead of `x/param`. Legacy types remain in order to facilitate parameter migration from the deprecated `x/params`. App developers should ensure that they execute `baseapp.MigrateParams` during their chain upgrade. These legacy types will be removed in a future release.
Expand Down
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 {}
11 changes: 6 additions & 5 deletions tests/integration/distribution/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ type KeeperTestSuite struct {
msgServer types.MsgServer
}

func TestDistributionTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

func (suite *KeeperTestSuite) SetupTest() {
app, err := simtestutil.Setup(testutil.AppConfig,
app, err := simtestutil.Setup(
testutil.AppConfig,
&suite.interfaceRegistry,
&suite.bankKeeper,
&suite.distrKeeper,
Expand Down Expand Up @@ -672,7 +677,3 @@ func (suite *KeeperTestSuite) TestGRPCCommunityPool() {
})
}
}

func TestDistributionTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
74 changes: 74 additions & 0 deletions tests/integration/distribution/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package keeper_test

import (
"cosmossdk.io/math"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

func (s *KeeperTestSuite) TestMsgUpdateParams() {
Expand Down Expand Up @@ -206,3 +211,72 @@ func (s *KeeperTestSuite) TestCommunityPoolSpend() {
})
}
}

func (s *KeeperTestSuite) TestMsgDepositValidatorRewardsPool() {
tstaking := stakingtestutil.NewHelper(s.T(), s.ctx, s.stakingKeeper)
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
tstaking.CreateValidator(s.valAddrs[1], valConsPk0, sdk.NewInt(100), true)

// mint a non-staking token and send to an account
amt := sdk.NewCoins(sdk.NewInt64Coin("foo", 500))
s.bankKeeper.MintCoins(s.ctx, minttypes.ModuleName, amt)
s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, minttypes.ModuleName, s.addrs[0], amt)

testCases := []struct {
name string
input *types.MsgDepositValidatorRewardsPool
expErr bool
expErrMsg string
}{
{
name: "happy path (staking token)",
input: &types.MsgDepositValidatorRewardsPool{
Authority: s.addrs[0].String(),
ValidatorAddress: s.valAddrs[1].String(),
Amount: sdk.NewCoins(sdk.NewCoin(s.stakingKeeper.BondDenom(s.ctx), sdk.NewInt(100))),
},
},
{
name: "happy path (non-staking token)",
input: &types.MsgDepositValidatorRewardsPool{
Authority: s.addrs[0].String(),
ValidatorAddress: s.valAddrs[1].String(),
Amount: amt,
},
},
{
name: "invalid validator",
input: &types.MsgDepositValidatorRewardsPool{
Authority: s.addrs[0].String(),
ValidatorAddress: sdk.ValAddress([]byte("addr1_______________")).String(),
Amount: sdk.NewCoins(sdk.NewCoin(s.stakingKeeper.BondDenom(s.ctx), sdk.NewInt(100))),
},
expErr: true,
expErrMsg: "validator does not exist",
},
}

for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
_, err := s.msgServer.DepositValidatorRewardsPool(s.ctx, tc.input)

if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)

valAddr, err := sdk.ValAddressFromBech32(tc.input.ValidatorAddress)
s.Require().NoError(err)

// check validator outstanding rewards
outstandingRewards := s.distrKeeper.GetValidatorOutstandingRewards(s.ctx, valAddr)
for _, c := range tc.input.Amount {
x := outstandingRewards.Rewards.AmountOf(c.Denom)
s.Require().Equal(x, sdk.NewDecFromInt(c.Amount))
}
}
})
}
}
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
}
Loading