Skip to content

Commit

Permalink
feat: Implemented consumer validators query including commission rate (
Browse files Browse the repository at this point in the history
…#2162)

* Implemented validator commission rate query in consumer chain

* Removed unnecessary check

* Removed unused code line
  • Loading branch information
kirdatatjana authored Aug 22, 2024
1 parent a0e1e2d commit bb3985a
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 125 deletions.
5 changes: 5 additions & 0 deletions proto/interchain_security/ccv/provider/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ message QueryConsumerValidatorsValidator {
tendermint.crypto.PublicKey consumer_key = 2;
// The power of the validator used on the consumer chain
int64 power = 3;
// The rate to charge delegators on the consumer chain, as a fraction
string rate = 4 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

message QueryConsumerValidatorsResponse {
Expand Down
22 changes: 21 additions & 1 deletion x/ccv/provider/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"google.golang.org/grpc/status"

errorsmod "cosmossdk.io/errors"
"cosmossdk.io/math"

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

Expand Down Expand Up @@ -330,14 +331,33 @@ func (k Keeper) QueryConsumerValidators(goCtx context.Context, req *types.QueryC
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

for _, v := range consumerValSet {

consAddr, err := sdk.ConsAddressFromBech32(sdk.ConsAddress(v.ProviderConsAddr).String())
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid provider address")
}

var rate math.LegacyDec
consumerRate, found := k.GetConsumerCommissionRate(ctx, consumerChainID, types.NewProviderConsAddress(consAddr))
if found {
rate = consumerRate
} else {
v, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
if err != nil {
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("unknown validator: %s", consAddr.String()))
}
rate = v.Commission.Rate
}

validators = append(validators, &types.QueryConsumerValidatorsValidator{
ProviderAddress: sdk.ConsAddress(v.ProviderConsAddr).String(),
ConsumerKey: v.PublicKey,
Power: v.Power,
Rate: rate,
})
}

return &types.QueryConsumerValidatorsResponse{
Validators: validators,
}, nil
Expand Down
21 changes: 18 additions & 3 deletions x/ccv/provider/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestQueryConsumerChainOptedInValidators(t *testing.T) {
func TestQueryConsumerValidators(t *testing.T) {
chainID := "chainID"

pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
pk, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

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

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

expectedResponse := types.QueryConsumerValidatorsResponse{
Validators: []*types.QueryConsumerValidatorsValidator{
{providerAddr1.String(), &consumerKey1, 1},
{providerAddr2.String(), &consumerKey2, 2},
{ProviderAddress: providerAddr1.String(), ConsumerKey: &consumerKey1, Power: 1, Rate: expectedCommissionRate1},
{ProviderAddress: providerAddr2.String(), ConsumerKey: &consumerKey2, Power: 2, Rate: expectedCommissionRate2},
},
}

Expand All @@ -132,6 +136,17 @@ func TestQueryConsumerValidators(t *testing.T) {
res, err := pk.QueryConsumerValidators(ctx, &req)
require.NoError(t, err)
require.Equal(t, &expectedResponse, res)

// validator with no set consumer commission rate
pk.DeleteConsumerCommissionRate(ctx, chainID, providerAddr1)
expectedCommissionRate := math.LegacyMustNewDecFromStr("0.456")
// because no consumer commission rate is set, the validator's set commission rate on the provider is used
val := stakingtypes.Validator{Commission: stakingtypes.Commission{CommissionRates: stakingtypes.CommissionRates{Rate: expectedCommissionRate}}}
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(
ctx, providerAddr1.ToSdkConsAddr()).Return(val, nil).Times(1)
res, _ = pk.QueryConsumerValidators(ctx, &req)
require.Equal(t, expectedCommissionRate, res.Validators[0].Rate)

}

func TestQueryConsumerChainsValidatorHasToValidate(t *testing.T) {
Expand Down
Loading

0 comments on commit bb3985a

Please sign in to comment.