Skip to content

Commit bb3985a

Browse files
authored
feat: Implemented consumer validators query including commission rate (#2162)
* Implemented validator commission rate query in consumer chain * Removed unnecessary check * Removed unused code line
1 parent a0e1e2d commit bb3985a

File tree

4 files changed

+214
-125
lines changed

4 files changed

+214
-125
lines changed

proto/interchain_security/ccv/provider/v1/query.proto

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,11 @@ message QueryConsumerValidatorsValidator {
292292
tendermint.crypto.PublicKey consumer_key = 2;
293293
// The power of the validator used on the consumer chain
294294
int64 power = 3;
295+
// The rate to charge delegators on the consumer chain, as a fraction
296+
string rate = 4 [
297+
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
298+
(gogoproto.nullable) = false
299+
];
295300
}
296301

297302
message QueryConsumerValidatorsResponse {

x/ccv/provider/keeper/grpc_query.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"google.golang.org/grpc/status"
99

1010
errorsmod "cosmossdk.io/errors"
11+
"cosmossdk.io/math"
1112

1213
sdk "github.com/cosmos/cosmos-sdk/types"
1314

@@ -330,14 +331,33 @@ func (k Keeper) QueryConsumerValidators(goCtx context.Context, req *types.QueryC
330331
if err != nil {
331332
return nil, status.Error(codes.Internal, err.Error())
332333
}
334+
333335
for _, v := range consumerValSet {
336+
337+
consAddr, err := sdk.ConsAddressFromBech32(sdk.ConsAddress(v.ProviderConsAddr).String())
338+
if err != nil {
339+
return nil, status.Error(codes.InvalidArgument, "invalid provider address")
340+
}
341+
342+
var rate math.LegacyDec
343+
consumerRate, found := k.GetConsumerCommissionRate(ctx, consumerChainID, types.NewProviderConsAddress(consAddr))
344+
if found {
345+
rate = consumerRate
346+
} else {
347+
v, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
348+
if err != nil {
349+
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("unknown validator: %s", consAddr.String()))
350+
}
351+
rate = v.Commission.Rate
352+
}
353+
334354
validators = append(validators, &types.QueryConsumerValidatorsValidator{
335355
ProviderAddress: sdk.ConsAddress(v.ProviderConsAddr).String(),
336356
ConsumerKey: v.PublicKey,
337357
Power: v.Power,
358+
Rate: rate,
338359
})
339360
}
340-
341361
return &types.QueryConsumerValidatorsResponse{
342362
Validators: validators,
343363
}, nil

x/ccv/provider/keeper/grpc_query_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func TestQueryConsumerChainOptedInValidators(t *testing.T) {
9999
func TestQueryConsumerValidators(t *testing.T) {
100100
chainID := "chainID"
101101

102-
pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
102+
pk, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
103103
defer ctrl.Finish()
104104

105105
req := types.QueryConsumerValidatorsRequest{
@@ -113,15 +113,19 @@ func TestQueryConsumerValidators(t *testing.T) {
113113
providerAddr1 := types.NewProviderConsAddress([]byte("providerAddr1"))
114114
consumerKey1 := cryptotestutil.NewCryptoIdentityFromIntSeed(1).TMProtoCryptoPublicKey()
115115
consumerValidator1 := types.ConsensusValidator{ProviderConsAddr: providerAddr1.ToSdkConsAddr(), Power: 1, PublicKey: &consumerKey1}
116+
expectedCommissionRate1 := math.LegacyMustNewDecFromStr("0.123")
117+
pk.SetConsumerCommissionRate(ctx, chainID, providerAddr1, expectedCommissionRate1)
116118

117119
providerAddr2 := types.NewProviderConsAddress([]byte("providerAddr2"))
118120
consumerKey2 := cryptotestutil.NewCryptoIdentityFromIntSeed(2).TMProtoCryptoPublicKey()
119121
consumerValidator2 := types.ConsensusValidator{ProviderConsAddr: providerAddr2.ToSdkConsAddr(), Power: 2, PublicKey: &consumerKey2}
122+
expectedCommissionRate2 := math.LegacyMustNewDecFromStr("0.123")
123+
pk.SetConsumerCommissionRate(ctx, chainID, providerAddr2, expectedCommissionRate2)
120124

121125
expectedResponse := types.QueryConsumerValidatorsResponse{
122126
Validators: []*types.QueryConsumerValidatorsValidator{
123-
{providerAddr1.String(), &consumerKey1, 1},
124-
{providerAddr2.String(), &consumerKey2, 2},
127+
{ProviderAddress: providerAddr1.String(), ConsumerKey: &consumerKey1, Power: 1, Rate: expectedCommissionRate1},
128+
{ProviderAddress: providerAddr2.String(), ConsumerKey: &consumerKey2, Power: 2, Rate: expectedCommissionRate2},
125129
},
126130
}
127131

@@ -132,6 +136,17 @@ func TestQueryConsumerValidators(t *testing.T) {
132136
res, err := pk.QueryConsumerValidators(ctx, &req)
133137
require.NoError(t, err)
134138
require.Equal(t, &expectedResponse, res)
139+
140+
// validator with no set consumer commission rate
141+
pk.DeleteConsumerCommissionRate(ctx, chainID, providerAddr1)
142+
expectedCommissionRate := math.LegacyMustNewDecFromStr("0.456")
143+
// because no consumer commission rate is set, the validator's set commission rate on the provider is used
144+
val := stakingtypes.Validator{Commission: stakingtypes.Commission{CommissionRates: stakingtypes.CommissionRates{Rate: expectedCommissionRate}}}
145+
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(
146+
ctx, providerAddr1.ToSdkConsAddr()).Return(val, nil).Times(1)
147+
res, _ = pk.QueryConsumerValidators(ctx, &req)
148+
require.Equal(t, expectedCommissionRate, res.Validators[0].Rate)
149+
135150
}
136151

137152
func TestQueryConsumerChainsValidatorHasToValidate(t *testing.T) {

0 commit comments

Comments
 (0)