syntax = "proto3";
package interchain_security.ccv.provider.v1;

option go_package = "github.com/cosmos/interchain-security/x/ccv/provider/types";

import "google/api/annotations.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "interchain_security/ccv/v1/ccv.proto";
import "interchain_security/ccv/consumer/v1/genesis.proto";
import "interchain_security/ccv/provider/v1/provider.proto";


service Query {
  // ConsumerGenesis queries the genesis state needed to start a consumer chain
  // whose proposal has been accepted
  rpc QueryConsumerGenesis(QueryConsumerGenesisRequest)
      returns (QueryConsumerGenesisResponse) {
    option (google.api.http).get =
        "/interchain_security/ccv/provider/consumer_genesis/{chain_id}";
  }

  // ConsumerChains queries active consumer chains supported by the provider
  // chain
  rpc QueryConsumerChains(QueryConsumerChainsRequest)
      returns (QueryConsumerChainsResponse) {
    option (google.api.http).get =
        "/interchain_security/ccv/provider/consumer_chains";
  }

  // QueryConsumerChainStarts queries consumer chain start proposals.
  rpc QueryConsumerChainStarts(QueryConsumerChainStartProposalsRequest)
      returns (QueryConsumerChainStartProposalsResponse) {
    option (google.api.http).get =
        "/interchain_security/ccv/provider/consumer_chain_start_proposals";
  }

  // QueryConsumerChainStops queries consumer chain stop proposals.
  rpc QueryConsumerChainStops(QueryConsumerChainStopProposalsRequest)
      returns (QueryConsumerChainStopProposalsResponse) {
    option (google.api.http).get =
        "/interchain_security/ccv/provider/consumer_chain_stop_proposals";
  }

  // QueryValidatorConsumerAddr queries the address
  // assigned by a validator for a consumer chain.
  rpc QueryValidatorConsumerAddr(QueryValidatorConsumerAddrRequest)
      returns (QueryValidatorConsumerAddrResponse) {
    option (google.api.http).get = "/interchain_security/ccv/provider/validator_consumer_addr";
  }

  // QueryProviderAddr returns the provider chain validator
  // given a consumer chain validator address
  rpc QueryValidatorProviderAddr(QueryValidatorProviderAddrRequest)
      returns (QueryValidatorProviderAddrResponse) {
    option (google.api.http).get = "/interchain_security/ccv/provider/validator_provider_addr";
  }

  // QueryThrottleState returns the main on-chain state relevant to currently throttled slash packets 
  rpc QueryThrottleState(QueryThrottleStateRequest)
      returns (QueryThrottleStateResponse) {
    option (google.api.http).get = "/interchain_security/ccv/provider/throttle_state";
  }

  // QueryThrottledConsumerPacketData returns a list of pending packet data instances
  // (slash packet and vsc matured) for a single consumer chain
  rpc QueryThrottledConsumerPacketData(QueryThrottledConsumerPacketDataRequest)
      returns (QueryThrottledConsumerPacketDataResponse) {
    option (google.api.http).get = "/interchain_security/ccv/provider/pending_consumer_packets";
  }
}

message QueryConsumerGenesisRequest { string chain_id = 1; }

message QueryConsumerGenesisResponse {
  interchain_security.ccv.consumer.v1.GenesisState genesis_state = 1
      [ (gogoproto.nullable) = false ];
}

message QueryConsumerChainsRequest {}

message QueryConsumerChainsResponse { repeated Chain chains = 1; }

message QueryConsumerChainStartProposalsRequest {}

message QueryConsumerChainStartProposalsResponse { 
  ConsumerAdditionProposals proposals = 1;
}

message QueryConsumerChainStopProposalsRequest {}

message QueryConsumerChainStopProposalsResponse { 
  ConsumerRemovalProposals proposals = 1;
}

message Chain {
  string chain_id = 1;
  string client_id = 2;
}

message QueryValidatorConsumerAddrRequest {
  option (gogoproto.equal) = false;
  option (gogoproto.goproto_getters) = false;
  // The id of the consumer chain
  string chain_id = 1;
  // The consensus address of the validator on the provider chain
  string provider_address = 2
      [ (gogoproto.moretags) = "yaml:\"address\"" ];
}

message QueryValidatorConsumerAddrResponse {
  // The address of the validator on the consumer chain
  string consumer_address = 1;
}

message QueryValidatorProviderAddrRequest {
  option (gogoproto.equal) = false;
  option (gogoproto.goproto_getters) = false;
  // The id of the provider chain
  string chain_id = 1;
  // The consensus address of the validator on the consumer chain
  string consumer_address = 2
      [ (gogoproto.moretags) = "yaml:\"address\"" ];
}

message QueryValidatorProviderAddrResponse {
  // The address of the validator on the provider chain
  string provider_address = 1;
}

message QueryThrottleStateRequest {}

message QueryThrottleStateResponse {
  // current slash_meter state
  int64 slash_meter = 1;
  // allowance of voting power units (int) that the slash meter is given per replenish period
  // this also serves as the max value for the meter.
  int64 slash_meter_allowance = 2;
  // next time the slash meter could potentially be replenished, iff it's not full
  google.protobuf.Timestamp next_replenish_candidate = 3
    [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
  // data relevant to currently throttled slash packets
  repeated ThrottledSlashPacket packets = 4;
}

message QueryThrottledConsumerPacketDataRequest {
  string chain_id = 1;
}

message QueryThrottledConsumerPacketDataResponse {
  string chain_id = 1;
  uint64 size = 2;
  repeated ThrottledPacketDataWrapper packetDataInstances = 3
    [(gogoproto.nullable) = false];
}

// A query wrapper type for the global entry and data relevant to a throttled slash packet.
message ThrottledSlashPacket {
  interchain_security.ccv.provider.v1.GlobalSlashEntry global_entry = 1
    [(gogoproto.nullable) = false];
  interchain_security.ccv.v1.SlashPacketData data = 2
    [(gogoproto.nullable) = false];
}

// ThrottledPacketDataWrapper contains either SlashPacketData or VSCMaturedPacketData
message ThrottledPacketDataWrapper {
  oneof data {
    interchain_security.ccv.v1.SlashPacketData slash_packet = 1;
    interchain_security.ccv.v1.VSCMaturedPacketData vsc_matured_packet = 2;
  }
}
