Skip to content

Commit

Permalink
feat: fix queries (#2209)
Browse files Browse the repository at this point in the history
* remove chain ID from all-pairs-valconsensus-address

* add consumer_id to Chain

* add GetAllLaunchedConsumerIds

* fix UT

* apply review suggestions
  • Loading branch information
mpoke authored Sep 4, 2024
1 parent cb6b525 commit 7301916
Show file tree
Hide file tree
Showing 7 changed files with 448 additions and 361 deletions.
20 changes: 10 additions & 10 deletions proto/interchain_security/ccv/provider/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ service Query {
"/interchain_security/ccv/provider/registered_consumer_reward_denoms";
}

// QueryAllPairsValConAddrByConsumerChainID returns a list of pair valconsensus address
// QueryAllPairsValConsAddrByConsumer returns a list of pair valconsensus address
// between provider and consumer chain
rpc QueryAllPairsValConAddrByConsumerChainID (
QueryAllPairsValConAddrByConsumerChainIDRequest)
returns (QueryAllPairsValConAddrByConsumerChainIDResponse) {
rpc QueryAllPairsValConsAddrByConsumer (
QueryAllPairsValConsAddrByConsumerRequest)
returns (QueryAllPairsValConsAddrByConsumerResponse) {
option (google.api.http) = {
get: "/interchain_security/ccv/provider/address_pairs/{consumer_id}";
};
Expand Down Expand Up @@ -110,7 +110,7 @@ service Query {
};
}

// QueryConsumerValidators returns the latest set consumer-validator set for a given chainID
// QueryConsumerValidators returns the latest set consumer-validator set for a given consumer ID
// Note that this does not necessarily mean that the consumer chain is using this validator set at this exact moment
// because a VSCPacket could be delayed to be delivered on the consumer chain.
rpc QueryConsumerValidators(QueryConsumerValidatorsRequest)
Expand Down Expand Up @@ -168,7 +168,6 @@ message QueryConsumerChainsResponse { repeated Chain chains = 1; }
message Chain {
string chain_id = 1;
string client_id = 2;
// If chain with `chainID` is a Top-N chain, i.e., enforces at least one validator to validate chain `chainID`
uint32 top_N = 3;
// If the chain is a Top-N chain, this is the minimum power required to be in the top N.
// Otherwise, this is -1.
Expand All @@ -184,13 +183,14 @@ message Chain {
// Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain.
repeated string denylist = 8;
// The phase the consumer chain (Registered=0|Initialized=1|FailedToLaunch=2|Launched=3|Stopped=4)
ConsumerPhase phase = 9;
string phase = 9;
// The metadata of the consumer chain
ConsumerMetadata metadata = 10 [(gogoproto.nullable) = false ];
// Corresponds to the minimal amount of (provider chain) stake required to validate on the consumer chain.
uint64 min_stake = 11;
// Corresponds to whether inactive validators are allowed to validate the consumer chain.
bool allow_inactive_vals = 12;
string consumer_id = 13;
}

message QueryValidatorConsumerAddrRequest {
Expand Down Expand Up @@ -241,12 +241,12 @@ message QueryRegisteredConsumerRewardDenomsResponse {
repeated string denoms = 1;
}

message QueryAllPairsValConAddrByConsumerChainIDRequest {
message QueryAllPairsValConsAddrByConsumerRequest {
// The id of the consumer chain
string consumer_id = 1;
}

message QueryAllPairsValConAddrByConsumerChainIDResponse {
message QueryAllPairsValConsAddrByConsumerResponse {
repeated PairValConAddrProviderAndConsumer pair_val_con_addr = 1;
}

Expand Down Expand Up @@ -332,7 +332,7 @@ message QueryConsumerChainsValidatorHasToValidateRequest {
}

message QueryConsumerChainsValidatorHasToValidateResponse {
repeated string consumer_chain_ids = 1;
repeated string consumer_ids = 1;
}

message QueryValidatorConsumerCommissionRateRequest {
Expand Down
32 changes: 16 additions & 16 deletions x/ccv/provider/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewQueryCmd() *cobra.Command {
cmd.AddCommand(CmdProviderValidatorKey())
cmd.AddCommand(CmdThrottleState())
cmd.AddCommand(CmdRegisteredConsumerRewardDenoms())
cmd.AddCommand(CmdAllPairsValConAddrByConsumerChainID())
cmd.AddCommand(CmdAllPairsValConsAddrByConsumer())
cmd.AddCommand(CmdProviderParameters())
cmd.AddCommand(CmdConsumerChainOptedInValidators())
cmd.AddCommand(CmdConsumerValidators())
Expand Down Expand Up @@ -123,13 +123,13 @@ func CmdConsumerChains() *cobra.Command {
func CmdConsumerValidatorKeyAssignment() *cobra.Command {
bech32PrefixConsAddr := sdk.GetConfig().GetBech32ConsensusAddrPrefix()
cmd := &cobra.Command{
Use: "validator-consumer-key [chainid] [provider-validator-address]",
Use: "validator-consumer-key [consumerId] [provider-validator-address]",
Short: "Query assigned validator consensus public key for a consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Returns the currently assigned validator consensus public key for a
consumer chain, if one has been assigned.
Example:
$ %s query provider validator-consumer-key foochain %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
$ %s query provider validator-consumer-key 3 %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
`,
version.AppName, bech32PrefixConsAddr,
),
Expand Down Expand Up @@ -285,10 +285,10 @@ $ %s query provider registered-consumer-reward-denoms
return cmd
}

func CmdAllPairsValConAddrByConsumerChainID() *cobra.Command {
func CmdAllPairsValConsAddrByConsumer() *cobra.Command {
cmd := &cobra.Command{
Use: "all-pairs-valconsensus-address [consumer-chain-id]",
Short: "Query all pairs of valconsensus address by consumer chainId.",
Use: "all-pairs-valconsensus-address [consumer-id]",
Short: "Query all pairs of valconsensus address by consumer ID.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
Expand All @@ -297,8 +297,8 @@ func CmdAllPairsValConAddrByConsumerChainID() *cobra.Command {
}
queryClient := types.NewQueryClient(clientCtx)

req := types.QueryAllPairsValConAddrByConsumerChainIDRequest{ConsumerId: args[0]}
res, err := queryClient.QueryAllPairsValConAddrByConsumerChainID(cmd.Context(), &req)
req := types.QueryAllPairsValConsAddrByConsumerRequest{ConsumerId: args[0]}
res, err := queryClient.QueryAllPairsValConsAddrByConsumer(cmd.Context(), &req)
if err != nil {
return err
}
Expand Down Expand Up @@ -346,15 +346,15 @@ $ %s query provider params
return cmd
}

// Command to query opted-in validators by consumer chain ID
// Command to query opted-in validators by consumer ID
func CmdConsumerChainOptedInValidators() *cobra.Command {
cmd := &cobra.Command{
Use: "consumer-opted-in-validators [chainid]",
Use: "consumer-opted-in-validators [consumer-id]",
Short: "Query opted-in validators for a given consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Query opted-in validators for a given consumer chain.
Example:
$ %s consumer-opted-in-validators foochain
$ %s consumer-opted-in-validators 3
`, version.AppName),
),
Args: cobra.ExactArgs(1),
Expand All @@ -380,16 +380,16 @@ $ %s consumer-opted-in-validators foochain
return cmd
}

// Command to query the consumer validators by consumer chain ID
// Command to query the consumer validators by consumer ID
func CmdConsumerValidators() *cobra.Command {
cmd := &cobra.Command{
Use: "consumer-validators [chainid]",
Use: "consumer-validators [consumer-id]",
Short: "Query the last set consumer-validator set for a given consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Query the last set consumer-validator set for a given consumer chain.
Note that this does not necessarily mean that the consumer chain is currently using this validator set because a VSCPacket could be delayed, etc.
Example:
$ %s consumer-validators foochain
$ %s consumer-validators 3
`, version.AppName),
),
Args: cobra.ExactArgs(1),
Expand Down Expand Up @@ -462,12 +462,12 @@ $ %s has-to-validate %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
func CmdValidatorConsumerCommissionRate() *cobra.Command {
bech32PrefixConsAddr := sdk.GetConfig().GetBech32ConsensusAddrPrefix()
cmd := &cobra.Command{
Use: "validator-consumer-commission-rate [chainid] [provider-validator-address]",
Use: "validator-consumer-commission-rate [consumer-id] [provider-validator-address]",
Short: "Query the consumer commission rate a validator charges on a consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Query the consumer commission rate a validator charges on a consumer chain.
Example:
$ %s validator-consumer-commission-rate foochain %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
$ %s validator-consumer-commission-rate 3 %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
`, version.AppName, bech32PrefixConsAddr),
),
Args: cobra.ExactArgs(2),
Expand Down
65 changes: 22 additions & 43 deletions x/ccv/provider/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import (
"context"
"fmt"
"sort"
"strconv"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

errorsmod "cosmossdk.io/errors"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/interchain-security/v5/x/ccv/provider/types"
ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types"
Expand Down Expand Up @@ -51,31 +49,13 @@ func (k Keeper) QueryConsumerChains(goCtx context.Context, req *types.QueryConsu
ctx := sdk.UnwrapSDKContext(goCtx)

consumerIds := []string{}
phaseFilter := req.Phase

// if the phase filter is set Launched get consumer from the state directly
if phaseFilter == types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED {
consumerIds = append(consumerIds, k.GetAllRegisteredConsumerIds(ctx)...)
// otherwise iterate over all the consumer using the last unused consumer Id
} else {
firstUnusedConsumerId, ok := k.GetConsumerId(ctx)
if !ok {
return &types.QueryConsumerChainsResponse{}, nil
}
for i := uint64(0); i < firstUnusedConsumerId; i++ {
// if the phase filter is set, verify that the consumer has the same phase
if phaseFilter != types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED {
p := k.GetConsumerPhase(ctx, strconv.FormatInt(int64(i), 10))
if p == types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED {
return nil, status.Error(codes.Internal, fmt.Sprintf("cannot retrieve phase for consumer id: %d", i))
}
if p != phaseFilter {
continue
}
}

consumerIds = append(consumerIds, strconv.FormatInt(int64(i), 10))
for _, consumerID := range k.GetAllConsumerIds(ctx) {
phase := k.GetConsumerPhase(ctx, consumerID)
if req.Phase != types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED && req.Phase != phase {
// ignore consumer chain
continue
}
consumerIds = append(consumerIds, consumerID)
}

// set limit to default value
Expand All @@ -84,12 +64,12 @@ func (k Keeper) QueryConsumerChains(goCtx context.Context, req *types.QueryConsu
// update limit if specified
limit = int(req.Limit)
}
if len(consumerIds) > limit {
consumerIds = consumerIds[:limit]
}

chains := make([]*types.Chain, math.Min(len(consumerIds), limit))
chains := make([]*types.Chain, len(consumerIds))
for i, cID := range consumerIds {
if i == limit {
break
}
c, err := k.GetConsumerChain(ctx, cID)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
Expand All @@ -108,6 +88,7 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, consumerId string) (types.Chai
}

clientID, _ := k.GetConsumerClientId(ctx, consumerId)

powerShapingParameters, err := k.GetConsumerPowerShapingParameters(ctx, consumerId)
if err != nil {
return types.Chain{}, fmt.Errorf("cannot find power shaping parameters for consumer (%s): %s", consumerId, err.Error())
Expand All @@ -116,15 +97,9 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, consumerId string) (types.Chai
// Get the minimal power in the top N for the consumer chain
minPowerInTopN, found := k.GetMinimumPowerInTopN(ctx, consumerId)
if !found {
k.Logger(ctx).Error("failed to get minimum power in top N, treating as -1", "chain", consumerId)
minPowerInTopN = -1
}

phase := k.GetConsumerPhase(ctx, consumerId)
if phase == types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED {
return types.Chain{}, fmt.Errorf("cannot find phase for consumer (%s)", consumerId)
}

allowlist := k.GetAllowList(ctx, consumerId)
strAllowlist := make([]string, len(allowlist))
for i, addr := range allowlist {
Expand All @@ -148,10 +123,11 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, consumerId string) (types.Chai
ValidatorsPowerCap: powerShapingParameters.ValidatorsPowerCap,
Allowlist: strAllowlist,
Denylist: strDenylist,
Phase: phase,
Phase: k.GetConsumerPhase(ctx, consumerId).String(),
Metadata: metadata,
AllowInactiveVals: powerShapingParameters.AllowInactiveVals,
MinStake: powerShapingParameters.MinStake,
ConsumerId: consumerId,
}, nil
}

Expand Down Expand Up @@ -243,7 +219,10 @@ func (k Keeper) QueryRegisteredConsumerRewardDenoms(goCtx context.Context, req *
}, nil
}

func (k Keeper) QueryAllPairsValConAddrByConsumerChainID(goCtx context.Context, req *types.QueryAllPairsValConAddrByConsumerChainIDRequest) (*types.QueryAllPairsValConAddrByConsumerChainIDResponse, error) {
func (k Keeper) QueryAllPairsValConsAddrByConsumer(
goCtx context.Context,
req *types.QueryAllPairsValConsAddrByConsumerRequest,
) (*types.QueryAllPairsValConsAddrByConsumerResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
Expand All @@ -270,7 +249,7 @@ func (k Keeper) QueryAllPairsValConAddrByConsumerChainID(goCtx context.Context,
})
}

return &types.QueryAllPairsValConAddrByConsumerChainIDResponse{
return &types.QueryAllPairsValConsAddrByConsumerResponse{
PairValConAddr: pairValConAddrs,
}, nil
}
Expand Down Expand Up @@ -445,14 +424,14 @@ func (k Keeper) QueryConsumerChainsValidatorHasToValidate(goCtx context.Context,
// get all the consumer chains for which the validator is either already
// opted-in, currently a consumer validator or if its voting power is within the TopN validators
consumersToValidate := []string{}
for _, consumerChainID := range k.GetAllRegisteredConsumerIds(ctx) {
if hasToValidate, err := k.hasToValidate(ctx, provAddr, consumerChainID); err == nil && hasToValidate {
consumersToValidate = append(consumersToValidate, consumerChainID)
for _, consumerId := range k.GetAllLaunchedConsumerIds(ctx) {
if hasToValidate, err := k.hasToValidate(ctx, provAddr, consumerId); err == nil && hasToValidate {
consumersToValidate = append(consumersToValidate, consumerId)
}
}

return &types.QueryConsumerChainsValidatorHasToValidateResponse{
ConsumerChainIds: consumersToValidate,
ConsumerIds: consumersToValidate,
}, nil
}

Expand Down
Loading

0 comments on commit 7301916

Please sign in to comment.