From e47e04a571749b8b3d4428139ca19078e676e409 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 26 Jul 2024 16:56:28 +0200
Subject: [PATCH 01/11] Add BlocksUntilNextEpoch query
---
.../ccv/provider/v1/query.proto | 15 +
x/ccv/provider/client/cli/query.go | 27 +
x/ccv/provider/keeper/grpc_query.go | 9 +
x/ccv/provider/keeper/relay.go | 9 +-
x/ccv/provider/keeper/relay_test.go | 27 +
x/ccv/provider/types/query.pb.go | 573 ++++++++++++++----
x/ccv/provider/types/query.pb.gw.go | 65 ++
7 files changed, 597 insertions(+), 128 deletions(-)
diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto
index 9ea3aa6bec..1acd816c3b 100644
--- a/proto/interchain_security/ccv/provider/v1/query.proto
+++ b/proto/interchain_security/ccv/provider/v1/query.proto
@@ -143,6 +143,14 @@ service Query {
option (google.api.http).get =
"/interchain_security/ccv/provider/consumer_validators/{chain_id}";
}
+
+ // QueryBlocksUntilNextEpoch returns the number of blocks until the next epoch
+ // starts and validator updates are sent to the consumer chains
+ rpc QueryBlocksUntilNextEpoch(QueryBlocksUntilNextEpochRequest)
+ returns (QueryBlocksUntilNextEpochResponse) {
+ option (google.api.http).get =
+ "/interchain_security/ccv/provider/blocks_until_next_epoch";
+ }
}
message QueryConsumerGenesisRequest { string chain_id = 1; }
@@ -326,3 +334,10 @@ message QueryOldestUnconfirmedVscResponse {
interchain_security.ccv.provider.v1.VscSendTimestamp vsc_send_timestamp = 1
[ (gogoproto.nullable) = false ];
}
+
+message QueryBlocksUntilNextEpochRequest { }
+
+message QueryBlocksUntilNextEpochResponse {
+ // The number of blocks until the next epoch starts
+ uint64 blocks_until_next_epoch = 1;
+}
\ No newline at end of file
diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go
index 697fccbb76..da84252dfc 100644
--- a/x/ccv/provider/client/cli/query.go
+++ b/x/ccv/provider/client/cli/query.go
@@ -596,3 +596,30 @@ func CmdOldestUnconfirmedVsc() *cobra.Command {
return cmd
}
+
+func CmdBlocksUntilNextEpoch() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "blocks-until-next-epoch",
+ Short: "Query the number of blocks until the next epoch begins and validator updates are sent to consumer chain",
+ Args: cobra.ExactArgs(0),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, err := client.GetClientQueryContext(cmd)
+ if err != nil {
+ return err
+ }
+ queryClient := types.NewQueryClient(clientCtx)
+
+ req := &types.QueryBlocksUntilNextEpochRequest{}
+ res, err := queryClient.QueryBlocksUntilNextEpoch(cmd.Context(), req)
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+
+ flags.AddQueryFlagsToCmd(cmd)
+
+ return cmd
+}
diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go
index d2a36c686d..17ba6150dc 100644
--- a/x/ccv/provider/keeper/grpc_query.go
+++ b/x/ccv/provider/keeper/grpc_query.go
@@ -488,3 +488,12 @@ func (k Keeper) QueryOldestUnconfirmedVsc(goCtx context.Context, req *types.Quer
return &types.QueryOldestUnconfirmedVscResponse{VscSendTimestamp: ts}, nil
}
+
+func (k Keeper) QueryBlocksUntilNextEpoch(goCtx context.Context, req *types.QueryBlocksUntilNextEpochRequest) (*types.QueryBlocksUntilNextEpochResponse, error) {
+ ctx := sdk.UnwrapSDKContext(goCtx)
+
+ // Calculate the blocks until the next epoch
+ blocksUntilNextEpoch := k.BlocksUntilNextEpoch(ctx)
+
+ return &types.QueryBlocksUntilNextEpochResponse{BlocksUntilNextEpoch: blocksUntilNextEpoch}, nil
+}
diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go
index 4d8f862c1b..fbc4f2acd4 100644
--- a/x/ccv/provider/keeper/relay.go
+++ b/x/ccv/provider/keeper/relay.go
@@ -149,7 +149,7 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) {
// notify the staking module to complete all matured unbonding ops
k.completeMaturedUnbondingOps(ctx)
- if ctx.BlockHeight()%k.GetBlocksPerEpoch(ctx) == 0 {
+ if k.BlocksUntilNextEpoch(ctx) == 0 {
// only queue and send VSCPackets at the boundaries of an epoch
// collect validator updates
@@ -162,6 +162,13 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) {
}
}
+// BlocksUntilNextEpoch returns the number of blocks until the next epoch starts
+// Returns 0 if the current block is the last block of the epoch
+func (k Keeper) BlocksUntilNextEpoch(ctx sdk.Context) uint64 {
+ epochLength := k.GetBlocksPerEpoch(ctx)
+ return uint64(epochLength - ctx.BlockHeight()%epochLength)
+}
+
// SendVSCPackets iterates over all registered consumers and sends pending
// VSC packets to the chains with established CCV channels.
// If the CCV channel is not established for a consumer chain,
diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go
index bd4211d2bf..7adbe83263 100644
--- a/x/ccv/provider/keeper/relay_test.go
+++ b/x/ccv/provider/keeper/relay_test.go
@@ -924,3 +924,30 @@ func TestQueueVSCPacketsWithPowerCapping(t *testing.T) {
require.Equal(t, expectedQueuedVSCPackets, actualQueuedVSCPackets)
}
+
+// TestBlocksUntilNextEpoch tests the `BlocksUntilNextEpoch` method
+func TestBlocksUntilNextEpoch(t *testing.T) {
+ providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
+ defer ctrl.Finish()
+
+ // 10 blocks constitute an epoch
+ params := providertypes.DefaultParams()
+ params.BlocksPerEpoch = 10
+ providerKeeper.SetParams(ctx, params)
+
+ // with block height of 1 we expect 9 blocks until the next epoch
+ ctx = ctx.WithBlockHeight(1)
+ require.Equal(t, uint64(9), providerKeeper.BlocksUntilNextEpoch(ctx))
+
+ // with block height of 5 we expect 5 blocks until the next epoch
+ ctx = ctx.WithBlockHeight(5)
+ require.Equal(t, uint64(5), providerKeeper.BlocksUntilNextEpoch(ctx))
+
+ // with block height of 10 we expect 0 blocks until the next epoch
+ ctx = ctx.WithBlockHeight(10)
+ require.Equal(t, uint64(10), providerKeeper.BlocksUntilNextEpoch(ctx))
+
+ // with block height of 15 we expect 5 blocks until the next epoch
+ ctx = ctx.WithBlockHeight(15)
+ require.Equal(t, uint64(5), providerKeeper.BlocksUntilNextEpoch(ctx))
+}
diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go
index 84e610776e..55c3610bd6 100644
--- a/x/ccv/provider/types/query.pb.go
+++ b/x/ccv/provider/types/query.pb.go
@@ -1744,6 +1744,87 @@ func (m *QueryOldestUnconfirmedVscResponse) GetVscSendTimestamp() VscSendTimesta
return VscSendTimestamp{}
}
+type QueryBlocksUntilNextEpochRequest struct {
+}
+
+func (m *QueryBlocksUntilNextEpochRequest) Reset() { *m = QueryBlocksUntilNextEpochRequest{} }
+func (m *QueryBlocksUntilNextEpochRequest) String() string { return proto.CompactTextString(m) }
+func (*QueryBlocksUntilNextEpochRequest) ProtoMessage() {}
+func (*QueryBlocksUntilNextEpochRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_422512d7b7586cd7, []int{36}
+}
+func (m *QueryBlocksUntilNextEpochRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *QueryBlocksUntilNextEpochRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_QueryBlocksUntilNextEpochRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *QueryBlocksUntilNextEpochRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_QueryBlocksUntilNextEpochRequest.Merge(m, src)
+}
+func (m *QueryBlocksUntilNextEpochRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *QueryBlocksUntilNextEpochRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_QueryBlocksUntilNextEpochRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QueryBlocksUntilNextEpochRequest proto.InternalMessageInfo
+
+type QueryBlocksUntilNextEpochResponse struct {
+ // The number of blocks until the next epoch starts
+ BlocksUntilNextEpoch uint64 `protobuf:"varint,1,opt,name=blocks_until_next_epoch,json=blocksUntilNextEpoch,proto3" json:"blocks_until_next_epoch,omitempty"`
+}
+
+func (m *QueryBlocksUntilNextEpochResponse) Reset() { *m = QueryBlocksUntilNextEpochResponse{} }
+func (m *QueryBlocksUntilNextEpochResponse) String() string { return proto.CompactTextString(m) }
+func (*QueryBlocksUntilNextEpochResponse) ProtoMessage() {}
+func (*QueryBlocksUntilNextEpochResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_422512d7b7586cd7, []int{37}
+}
+func (m *QueryBlocksUntilNextEpochResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *QueryBlocksUntilNextEpochResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_QueryBlocksUntilNextEpochResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *QueryBlocksUntilNextEpochResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_QueryBlocksUntilNextEpochResponse.Merge(m, src)
+}
+func (m *QueryBlocksUntilNextEpochResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *QueryBlocksUntilNextEpochResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_QueryBlocksUntilNextEpochResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QueryBlocksUntilNextEpochResponse proto.InternalMessageInfo
+
+func (m *QueryBlocksUntilNextEpochResponse) GetBlocksUntilNextEpoch() uint64 {
+ if m != nil {
+ return m.BlocksUntilNextEpoch
+ }
+ return 0
+}
+
func init() {
proto.RegisterType((*QueryConsumerGenesisRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisRequest")
proto.RegisterType((*QueryConsumerGenesisResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisResponse")
@@ -1781,6 +1862,8 @@ func init() {
proto.RegisterType((*QueryValidatorConsumerCommissionRateResponse)(nil), "interchain_security.ccv.provider.v1.QueryValidatorConsumerCommissionRateResponse")
proto.RegisterType((*QueryOldestUnconfirmedVscRequest)(nil), "interchain_security.ccv.provider.v1.QueryOldestUnconfirmedVscRequest")
proto.RegisterType((*QueryOldestUnconfirmedVscResponse)(nil), "interchain_security.ccv.provider.v1.QueryOldestUnconfirmedVscResponse")
+ proto.RegisterType((*QueryBlocksUntilNextEpochRequest)(nil), "interchain_security.ccv.provider.v1.QueryBlocksUntilNextEpochRequest")
+ proto.RegisterType((*QueryBlocksUntilNextEpochResponse)(nil), "interchain_security.ccv.provider.v1.QueryBlocksUntilNextEpochResponse")
}
func init() {
@@ -1788,133 +1871,138 @@ func init() {
}
var fileDescriptor_422512d7b7586cd7 = []byte{
- // 2015 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcd, 0x6f, 0xdc, 0xc6,
- 0x15, 0x17, 0x57, 0x1f, 0x91, 0x46, 0xf1, 0x47, 0xc6, 0x6a, 0x22, 0x53, 0xca, 0xae, 0x42, 0xf7,
- 0x43, 0x96, 0x5d, 0x52, 0x92, 0x61, 0xc4, 0xb1, 0xab, 0xc8, 0x5a, 0xc9, 0x76, 0x16, 0x76, 0x62,
- 0x85, 0x96, 0xd5, 0xc2, 0x2d, 0x4a, 0x8f, 0xc9, 0xc9, 0x8a, 0x30, 0x97, 0x43, 0x71, 0xb8, 0xeb,
- 0x2c, 0x8c, 0x1c, 0xd2, 0x43, 0x9b, 0x53, 0x11, 0xf4, 0x03, 0xe8, 0x31, 0x97, 0x1e, 0x7b, 0xe9,
- 0xa1, 0xc8, 0x9f, 0x90, 0x5b, 0x53, 0xe4, 0x52, 0xf4, 0xe0, 0x16, 0x72, 0x0f, 0x45, 0x0f, 0x45,
- 0x61, 0x14, 0xe8, 0xa9, 0x40, 0xc1, 0xe1, 0xf0, 0x6b, 0x97, 0xbb, 0x4b, 0xee, 0x2a, 0xb7, 0xe5,
- 0xcc, 0xbc, 0xdf, 0xbc, 0xf7, 0xe6, 0xbd, 0x37, 0xef, 0x37, 0x0b, 0x14, 0xd3, 0xf6, 0xb0, 0xab,
- 0x1f, 0x20, 0xd3, 0xd6, 0x28, 0xd6, 0x9b, 0xae, 0xe9, 0xb5, 0x15, 0x5d, 0x6f, 0x29, 0x8e, 0x4b,
- 0x5a, 0xa6, 0x81, 0x5d, 0xa5, 0xb5, 0xa6, 0x1c, 0x36, 0xb1, 0xdb, 0x96, 0x1d, 0x97, 0x78, 0x04,
- 0x9e, 0xcb, 0x10, 0x90, 0x75, 0xbd, 0x25, 0x87, 0x02, 0x72, 0x6b, 0x4d, 0x5c, 0xac, 0x13, 0x52,
- 0xb7, 0xb0, 0x82, 0x1c, 0x53, 0x41, 0xb6, 0x4d, 0x3c, 0xe4, 0x99, 0xc4, 0xa6, 0x01, 0x84, 0x38,
- 0x57, 0x27, 0x75, 0xc2, 0x7e, 0x2a, 0xfe, 0x2f, 0x3e, 0x5a, 0xe1, 0x32, 0xec, 0xeb, 0x51, 0xf3,
- 0x03, 0xc5, 0x33, 0x1b, 0x98, 0x7a, 0xa8, 0xe1, 0xf0, 0x05, 0xeb, 0x79, 0x54, 0x8d, 0xb4, 0x08,
- 0x64, 0x56, 0x7b, 0xc9, 0xb4, 0xd6, 0x14, 0x7a, 0x80, 0x5c, 0x6c, 0x68, 0x3a, 0xb1, 0x69, 0xb3,
- 0x11, 0x49, 0x7c, 0xab, 0x8f, 0xc4, 0x13, 0xd3, 0xc5, 0x7c, 0xd9, 0xa2, 0x87, 0x6d, 0x03, 0xbb,
- 0x0d, 0xd3, 0xf6, 0x14, 0xdd, 0x6d, 0x3b, 0x1e, 0x51, 0x1e, 0xe3, 0x76, 0x68, 0xe1, 0x59, 0x9d,
- 0xd0, 0x06, 0xa1, 0x5a, 0x60, 0x64, 0xf0, 0x11, 0x4c, 0x49, 0x57, 0xc0, 0xc2, 0xfb, 0xbe, 0x3b,
- 0xb7, 0xf9, 0xb6, 0xb7, 0xb0, 0x8d, 0xa9, 0x49, 0x55, 0x7c, 0xd8, 0xc4, 0xd4, 0x83, 0x67, 0xc1,
- 0x74, 0xb0, 0xb7, 0x69, 0xcc, 0x0b, 0x4b, 0xc2, 0xf2, 0x8c, 0xfa, 0x12, 0xfb, 0xae, 0x19, 0xd2,
- 0x53, 0xb0, 0x98, 0x2d, 0x49, 0x1d, 0x62, 0x53, 0x0c, 0x7f, 0x08, 0x4e, 0xd4, 0x83, 0x21, 0x8d,
- 0x7a, 0xc8, 0xc3, 0x4c, 0x7e, 0x76, 0x7d, 0x55, 0xee, 0x75, 0x62, 0xad, 0x35, 0xb9, 0x03, 0xeb,
- 0x9e, 0x2f, 0x57, 0x9d, 0xf8, 0xe2, 0x59, 0x65, 0x4c, 0x7d, 0xb9, 0x9e, 0x18, 0x93, 0x16, 0x81,
- 0x98, 0xda, 0x7c, 0xdb, 0x87, 0x0b, 0xb5, 0x96, 0x50, 0x87, 0x51, 0xe1, 0x2c, 0xd7, 0xac, 0x0a,
- 0xa6, 0xd8, 0xf6, 0x74, 0x5e, 0x58, 0x1a, 0x5f, 0x9e, 0x5d, 0x5f, 0x91, 0x73, 0x04, 0x91, 0xcc,
- 0x40, 0x54, 0x2e, 0x29, 0x9d, 0x07, 0xdf, 0xe9, 0xde, 0xe2, 0x9e, 0x87, 0x5c, 0x6f, 0xd7, 0x25,
- 0x0e, 0xa1, 0xc8, 0x8a, 0xb4, 0xf9, 0x44, 0x00, 0xcb, 0x83, 0xd7, 0x72, 0xdd, 0x7e, 0x04, 0x66,
- 0x9c, 0x70, 0x90, 0x7b, 0xec, 0xed, 0x7c, 0xea, 0x71, 0xf0, 0x2d, 0xc3, 0x30, 0xfd, 0xe8, 0x8e,
- 0xa1, 0x63, 0x40, 0x69, 0x19, 0x7c, 0x3b, 0x4b, 0x13, 0xe2, 0x74, 0x29, 0xfd, 0x53, 0x21, 0xdb,
- 0xc0, 0xd4, 0xd2, 0xe8, 0xa4, 0xbb, 0x74, 0xde, 0x28, 0xa4, 0xb3, 0x8a, 0x1b, 0xa4, 0x85, 0xac,
- 0x4c, 0x95, 0x7f, 0x53, 0x02, 0x93, 0x6c, 0xef, 0x3e, 0xb1, 0x08, 0x17, 0xc0, 0x8c, 0x6e, 0x99,
- 0xd8, 0xf6, 0xfc, 0xb9, 0x12, 0x9b, 0x9b, 0x0e, 0x06, 0x6a, 0x06, 0x3c, 0x03, 0x26, 0x3d, 0xe2,
- 0x68, 0xef, 0xcd, 0x8f, 0x2f, 0x09, 0xcb, 0x27, 0xd4, 0x09, 0x8f, 0x38, 0xef, 0xc1, 0x15, 0x00,
- 0x1b, 0xa6, 0xad, 0x39, 0xe4, 0x09, 0x76, 0x35, 0xd3, 0xd6, 0x82, 0x15, 0x13, 0x4b, 0xc2, 0xf2,
- 0xb8, 0x7a, 0xb2, 0x61, 0xda, 0xbb, 0xfe, 0x44, 0xcd, 0xde, 0xf3, 0xd7, 0xae, 0x82, 0xb9, 0x16,
- 0xb2, 0x4c, 0x03, 0x79, 0xc4, 0xa5, 0x5c, 0x44, 0x47, 0xce, 0xfc, 0x24, 0xc3, 0x83, 0xf1, 0x1c,
- 0x13, 0xda, 0x46, 0x0e, 0x5c, 0x01, 0xaf, 0x44, 0xa3, 0x1a, 0xc5, 0x1e, 0x5b, 0x3e, 0xc5, 0x96,
- 0x9f, 0x8a, 0x26, 0xee, 0x61, 0xcf, 0x5f, 0xbb, 0x08, 0x66, 0x90, 0x65, 0x91, 0x27, 0x96, 0x49,
- 0xbd, 0xf9, 0x97, 0x96, 0xc6, 0x97, 0x67, 0xd4, 0x78, 0x00, 0x8a, 0x60, 0xda, 0xc0, 0x76, 0x9b,
- 0x4d, 0x4e, 0xb3, 0xc9, 0xe8, 0x5b, 0xfa, 0x99, 0x00, 0xde, 0x60, 0x67, 0xb4, 0x1f, 0x42, 0x26,
- 0x82, 0xc0, 0x1d, 0x9c, 0xc2, 0x70, 0x03, 0x9c, 0x0e, 0x8f, 0x43, 0x43, 0x86, 0xe1, 0x62, 0x4a,
- 0x03, 0xef, 0x55, 0xe1, 0x8b, 0x67, 0x95, 0x93, 0x6d, 0xd4, 0xb0, 0xae, 0x4a, 0x7c, 0x42, 0x52,
- 0x4f, 0x85, 0x6b, 0xb7, 0x82, 0x91, 0xab, 0xd3, 0x9f, 0x7c, 0x56, 0x19, 0xfb, 0xc7, 0x67, 0x95,
- 0x31, 0xe9, 0x2e, 0x90, 0xfa, 0x29, 0xc2, 0xe3, 0xe4, 0x3c, 0x38, 0x1d, 0x56, 0xb7, 0x68, 0xbb,
- 0x40, 0xa3, 0x53, 0x7a, 0x62, 0xbd, 0xbf, 0x59, 0xb7, 0x69, 0xbb, 0x89, 0xcd, 0xf3, 0x99, 0xd6,
- 0xb5, 0x57, 0x1f, 0xd3, 0x3a, 0xf6, 0xef, 0x67, 0x5a, 0x5a, 0x91, 0xd8, 0xb4, 0x2e, 0x4f, 0x72,
- 0xd3, 0x3a, 0xbc, 0x26, 0x2d, 0x80, 0xb3, 0x0c, 0x70, 0xef, 0xc0, 0x25, 0x9e, 0x67, 0x61, 0x56,
- 0xd0, 0xc2, 0xb4, 0xfb, 0x93, 0xc0, 0x0b, 0x5b, 0xc7, 0x2c, 0xdf, 0xa6, 0x02, 0x66, 0xa9, 0x85,
- 0xe8, 0x81, 0xd6, 0xc0, 0x1e, 0x76, 0xd9, 0x0e, 0xe3, 0x2a, 0x60, 0x43, 0xef, 0xfa, 0x23, 0x70,
- 0x1d, 0x7c, 0x23, 0xb1, 0x40, 0x63, 0x71, 0x84, 0x6c, 0x1d, 0x33, 0xdb, 0xc7, 0xd5, 0x33, 0xf1,
- 0xd2, 0xad, 0x70, 0x0a, 0xfe, 0x18, 0xcc, 0xdb, 0xf8, 0x43, 0x4f, 0x73, 0xb1, 0x63, 0x61, 0xdb,
- 0xa4, 0x07, 0x9a, 0x8e, 0x6c, 0xc3, 0x37, 0x16, 0xb3, 0x94, 0x99, 0x5d, 0x17, 0xe5, 0xe0, 0x32,
- 0x94, 0xc3, 0xcb, 0x50, 0xde, 0x0b, 0x2f, 0xc3, 0xea, 0xb4, 0x5f, 0x9d, 0x3f, 0xfd, 0x6b, 0x45,
- 0x50, 0x5f, 0xf5, 0x51, 0xd4, 0x10, 0x64, 0x3b, 0xc4, 0x90, 0x2e, 0x82, 0x15, 0x66, 0x92, 0x8a,
- 0xeb, 0x26, 0xf5, 0xb0, 0x8b, 0x8d, 0x38, 0xef, 0x9f, 0x20, 0xd7, 0xd8, 0xc1, 0x36, 0x69, 0x44,
- 0x85, 0xe7, 0x06, 0xb8, 0x90, 0x6b, 0x35, 0xf7, 0xc8, 0xab, 0x60, 0xca, 0x60, 0x23, 0xac, 0x96,
- 0xcf, 0xa8, 0xfc, 0x4b, 0x2a, 0xf3, 0xdb, 0x29, 0xa8, 0x29, 0xd8, 0x60, 0x25, 0xa4, 0xb6, 0x13,
- 0x6d, 0xf3, 0xb1, 0x00, 0x5e, 0xef, 0xb1, 0x80, 0x23, 0x3f, 0x04, 0x27, 0x9d, 0xe4, 0x5c, 0x78,
- 0x5b, 0xac, 0xe7, 0x2a, 0x6d, 0x29, 0x58, 0x7e, 0x85, 0x75, 0xe0, 0x49, 0x35, 0x70, 0x22, 0xb5,
- 0x0c, 0xce, 0x03, 0x1e, 0xbf, 0x3b, 0xe9, 0x70, 0xde, 0x81, 0x65, 0x00, 0xc2, 0x92, 0x58, 0xdb,
- 0x61, 0x87, 0x39, 0xa1, 0x26, 0x46, 0xa4, 0x3b, 0x40, 0x61, 0xd6, 0x6c, 0x59, 0xd6, 0x2e, 0x32,
- 0x5d, 0xba, 0x8f, 0xac, 0x6d, 0x62, 0xfb, 0x21, 0x57, 0x4d, 0x57, 0xf0, 0xda, 0x4e, 0x8e, 0xab,
- 0xfd, 0xb7, 0x02, 0x58, 0xcd, 0x0f, 0xc7, 0xfd, 0x75, 0x08, 0x5e, 0x71, 0x90, 0xe9, 0x6a, 0x2d,
- 0x64, 0xf9, 0x4d, 0x0c, 0x4b, 0x03, 0xee, 0xb2, 0x9b, 0xf9, 0x5c, 0x86, 0x4c, 0x37, 0xde, 0x28,
- 0x4a, 0x33, 0x3b, 0x0e, 0x80, 0x93, 0x4e, 0x6a, 0x89, 0xf4, 0x1f, 0x01, 0xbc, 0x31, 0x50, 0x0a,
- 0xde, 0xec, 0x95, 0x9b, 0xd5, 0x85, 0x17, 0xcf, 0x2a, 0xaf, 0x05, 0xa5, 0xa0, 0x73, 0x45, 0x77,
- 0xb9, 0xf3, 0x71, 0x7a, 0x94, 0x94, 0x04, 0x4e, 0xe7, 0x8a, 0xee, 0xda, 0x02, 0x37, 0xc1, 0xcb,
- 0xd1, 0xaa, 0xc7, 0xb8, 0xcd, 0x73, 0x6c, 0x51, 0x8e, 0x5b, 0x38, 0x39, 0x68, 0xe1, 0xe4, 0xdd,
- 0xe6, 0x23, 0xcb, 0xd4, 0x6f, 0xe3, 0xb6, 0x3a, 0x1b, 0x4a, 0xdc, 0xc6, 0x6d, 0x69, 0x0e, 0xc0,
- 0x20, 0x74, 0x91, 0x8b, 0xe2, 0xc4, 0x79, 0x08, 0xce, 0xa4, 0x46, 0xf9, 0xb1, 0xd4, 0xc0, 0x94,
- 0xc3, 0x46, 0xf8, 0xcd, 0x7c, 0x21, 0xe7, 0x59, 0xf8, 0x22, 0x3c, 0x6e, 0x39, 0x80, 0x74, 0x8b,
- 0x27, 0x72, 0x2a, 0x02, 0xee, 0x3a, 0x1e, 0x36, 0x6a, 0x76, 0x54, 0x1e, 0xf3, 0xb4, 0x8e, 0x87,
- 0x3c, 0xc7, 0x07, 0x01, 0x45, 0xfd, 0xda, 0xeb, 0xc9, 0xfb, 0xb7, 0xe3, 0xa4, 0x70, 0x98, 0xfa,
- 0x0b, 0x89, 0x8b, 0x38, 0x7d, 0x74, 0x98, 0x4a, 0xd7, 0x40, 0x39, 0xb5, 0x65, 0x21, 0x7d, 0x3f,
- 0x17, 0xc0, 0x52, 0x0f, 0xe9, 0xe8, 0x57, 0xe6, 0x65, 0x2a, 0xe4, 0xbe, 0x4c, 0xbb, 0xa2, 0xa2,
- 0x54, 0x30, 0x2a, 0xe0, 0x1c, 0x98, 0x64, 0xad, 0x09, 0x8b, 0xa7, 0x71, 0x35, 0xf8, 0xf0, 0x9b,
- 0xcf, 0x4a, 0x4f, 0xc3, 0xb9, 0x7f, 0x31, 0x00, 0xb1, 0xeb, 0x78, 0xca, 0xde, 0xc8, 0x15, 0x26,
- 0x83, 0x9c, 0xa2, 0x26, 0x80, 0xa5, 0x43, 0x5e, 0x54, 0xd2, 0x5d, 0x79, 0xb4, 0xf6, 0x1d, 0x44,
- 0xf7, 0x08, 0xff, 0x0a, 0xef, 0xc3, 0x11, 0x9d, 0x2a, 0x21, 0xb0, 0x56, 0x60, 0x4b, 0xee, 0x8e,
- 0x8b, 0x00, 0x46, 0x27, 0x11, 0x46, 0x44, 0x18, 0x63, 0x51, 0x05, 0x08, 0xaa, 0x9f, 0xc1, 0x3a,
- 0x95, 0x0b, 0xd9, 0xbd, 0xcf, 0x36, 0x69, 0x34, 0x4c, 0x4a, 0x4d, 0x62, 0xab, 0x09, 0x8b, 0xbe,
- 0xb6, 0x76, 0x4c, 0xaa, 0x83, 0x8b, 0xf9, 0x14, 0xe1, 0x76, 0xbe, 0x09, 0x26, 0xdc, 0x90, 0x97,
- 0xcd, 0x54, 0xcf, 0xf9, 0xa9, 0xfe, 0x97, 0x67, 0x95, 0x85, 0x80, 0x1e, 0x52, 0xe3, 0xb1, 0x6c,
- 0x12, 0xa5, 0x81, 0xbc, 0x03, 0xf9, 0x0e, 0xae, 0x23, 0xbd, 0xbd, 0x83, 0x75, 0x95, 0x09, 0x48,
- 0x1b, 0x3c, 0x1b, 0xee, 0x5a, 0x06, 0xa6, 0xde, 0x7d, 0x5b, 0x27, 0xf6, 0x07, 0xa6, 0xdb, 0xc0,
- 0xc6, 0x3e, 0xd5, 0x73, 0x64, 0xd3, 0xcf, 0xc3, 0xde, 0x2e, 0x5b, 0x9e, 0x6b, 0x67, 0x02, 0xd8,
- 0xa2, 0xba, 0x46, 0xb1, 0x6d, 0x68, 0x11, 0xf5, 0xe6, 0x35, 0xec, 0x72, 0xae, 0xe0, 0xdc, 0xa7,
- 0xfa, 0x3d, 0x6c, 0x1b, 0x71, 0xab, 0x12, 0x54, 0xb3, 0xd3, 0xad, 0x8e, 0xf1, 0xf5, 0xcf, 0x2b,
- 0x60, 0x92, 0x29, 0x04, 0x8f, 0x04, 0x30, 0x97, 0x45, 0x6a, 0xe1, 0xf5, 0xe2, 0xe9, 0x90, 0x66,
- 0xd2, 0xe2, 0xd6, 0x08, 0x08, 0x81, 0x4b, 0xa4, 0x1b, 0x3f, 0xf9, 0xea, 0xef, 0xbf, 0x2c, 0x6d,
- 0xc2, 0x8d, 0xc1, 0xaf, 0x24, 0x51, 0x00, 0x73, 0xd6, 0xac, 0x3c, 0x0d, 0x4f, 0xe3, 0x23, 0xf8,
- 0x95, 0xc0, 0x6f, 0x8a, 0x74, 0x56, 0xc0, 0xcd, 0xe2, 0x1a, 0xa6, 0x68, 0xb7, 0x78, 0x7d, 0x78,
- 0x00, 0x6e, 0xe1, 0x5b, 0xcc, 0xc2, 0x4b, 0x70, 0xad, 0x80, 0x85, 0x01, 0x21, 0x87, 0x1f, 0x97,
- 0xc0, 0x7c, 0x0f, 0x96, 0x4d, 0xe1, 0x9d, 0x21, 0x35, 0xcb, 0x24, 0xf4, 0xe2, 0xbb, 0xc7, 0x84,
- 0xc6, 0x8d, 0x7e, 0x87, 0x19, 0x5d, 0x85, 0xd7, 0x8b, 0x1a, 0xad, 0x51, 0x1f, 0x50, 0x8b, 0xb8,
- 0x32, 0xfc, 0x9f, 0x00, 0x5e, 0xcb, 0x26, 0xed, 0x14, 0xde, 0x1e, 0x5a, 0xe9, 0xee, 0xd7, 0x01,
- 0xf1, 0xce, 0xf1, 0x80, 0x71, 0x07, 0xdc, 0x62, 0x0e, 0xd8, 0x82, 0x9b, 0x43, 0x38, 0x80, 0x38,
- 0x09, 0xfb, 0xff, 0x1d, 0xb2, 0xa7, 0x4c, 0x1e, 0x0a, 0x6f, 0xe6, 0xd7, 0xba, 0x1f, 0xa3, 0x16,
- 0x6f, 0x8d, 0x8c, 0xc3, 0x0d, 0xdf, 0x62, 0x86, 0x5f, 0x83, 0x6f, 0xe5, 0x78, 0xf6, 0x8c, 0x9e,
- 0x13, 0x52, 0x1d, 0x66, 0x86, 0xc9, 0xc9, 0xde, 0x67, 0x28, 0x93, 0x33, 0x98, 0xf6, 0x50, 0x26,
- 0x67, 0x11, 0xe5, 0xe1, 0x4c, 0x4e, 0xdd, 0x8a, 0xf0, 0x8f, 0x02, 0xef, 0x7f, 0x53, 0x1c, 0x19,
- 0xbe, 0x9d, 0x5f, 0xc5, 0x2c, 0xea, 0x2d, 0x6e, 0x0e, 0x2d, 0xcf, 0x4d, 0xbb, 0xc2, 0x4c, 0x5b,
- 0x87, 0xab, 0x83, 0x4d, 0xf3, 0x38, 0x40, 0xf0, 0x32, 0x0a, 0x7f, 0x5d, 0x02, 0xe7, 0x72, 0x90,
- 0x5e, 0x78, 0x37, 0xbf, 0x8a, 0xb9, 0xc8, 0xb6, 0xb8, 0x7b, 0x7c, 0x80, 0xdc, 0x09, 0xb7, 0x99,
- 0x13, 0x6e, 0xc0, 0xed, 0xc1, 0x4e, 0x70, 0x23, 0xc4, 0x38, 0xa6, 0x5d, 0x86, 0xa9, 0x05, 0x24,
- 0x1e, 0xfe, 0xb3, 0x8b, 0xa4, 0xa7, 0xb9, 0x27, 0x85, 0x05, 0x6e, 0xd5, 0x1e, 0x2f, 0x01, 0x62,
- 0x75, 0x14, 0x08, 0x6e, 0x75, 0x95, 0x59, 0xfd, 0x3d, 0x78, 0x75, 0xb0, 0xd5, 0xe1, 0x1b, 0x80,
- 0xd6, 0x79, 0x81, 0xfd, 0xaa, 0xc4, 0x9f, 0x89, 0x73, 0x90, 0x6e, 0xb8, 0x97, 0x5f, 0xe9, 0xfc,
- 0x4f, 0x02, 0xe2, 0xfd, 0x63, 0x46, 0xe5, 0xde, 0xb9, 0xc6, 0xbc, 0x73, 0x19, 0x5e, 0x2a, 0x5c,
- 0xdf, 0x4d, 0x03, 0xfe, 0x5e, 0x00, 0xb3, 0x09, 0x5e, 0x0b, 0xdf, 0x2c, 0x70, 0x5c, 0x49, 0x7e,
- 0x2c, 0x5e, 0x29, 0x2e, 0xc8, 0xf5, 0x5f, 0x65, 0xfa, 0xaf, 0xc0, 0xe5, 0x1c, 0xa7, 0x1b, 0x28,
- 0xf9, 0x8b, 0x30, 0xa1, 0xfb, 0x33, 0xdc, 0x22, 0x09, 0x9d, 0x8b, 0x74, 0x17, 0x49, 0xe8, 0x7c,
- 0xe4, 0xbb, 0x48, 0x77, 0x42, 0x7c, 0x10, 0xcd, 0xb4, 0xb5, 0x98, 0xf4, 0x25, 0xfb, 0xce, 0x3f,
- 0x94, 0xc0, 0xf9, 0xdc, 0x6c, 0x0c, 0xde, 0x1f, 0xb6, 0x99, 0xec, 0x4b, 0x28, 0xc5, 0xfd, 0xe3,
- 0x86, 0xe5, 0x6e, 0x7a, 0xc0, 0xdc, 0xb4, 0x07, 0xd5, 0xc2, 0x9d, 0xab, 0xe6, 0x60, 0x37, 0xf6,
- 0x98, 0xf2, 0xb4, 0x93, 0x02, 0x7e, 0x04, 0x7f, 0x57, 0x02, 0xdf, 0xcc, 0xc3, 0xec, 0xe0, 0xee,
- 0x08, 0x8d, 0x49, 0x26, 0x5b, 0x15, 0xdf, 0x3f, 0x46, 0x44, 0xee, 0xa9, 0x87, 0xcc, 0x53, 0x0f,
- 0xe0, 0x0f, 0x8a, 0x78, 0x2a, 0x82, 0xd2, 0x7c, 0x06, 0x9a, 0x88, 0xaa, 0x2c, 0x7f, 0xfd, 0x57,
- 0xe0, 0x4f, 0xec, 0x59, 0x04, 0x13, 0x16, 0x78, 0xd9, 0xe8, 0x43, 0x70, 0xc5, 0x9b, 0xa3, 0xc2,
- 0x14, 0xbf, 0x30, 0x09, 0xc3, 0xd1, 0x9a, 0x31, 0x90, 0xd6, 0xa2, 0x7a, 0x32, 0xc5, 0xfe, 0xd5,
- 0x49, 0x00, 0x12, 0xb5, 0x66, 0x7b, 0x94, 0x17, 0x9d, 0xd0, 0xea, 0x9d, 0xd1, 0x40, 0x46, 0x60,
- 0x3c, 0x99, 0x35, 0xa5, 0xfa, 0xfd, 0x2f, 0x8e, 0xca, 0xc2, 0x97, 0x47, 0x65, 0xe1, 0x6f, 0x47,
- 0x65, 0xe1, 0xd3, 0xe7, 0xe5, 0xb1, 0x2f, 0x9f, 0x97, 0xc7, 0xfe, 0xfc, 0xbc, 0x3c, 0xf6, 0x60,
- 0xa3, 0x6e, 0x7a, 0x07, 0xcd, 0x47, 0xb2, 0x4e, 0x1a, 0xfc, 0x1f, 0xef, 0xc4, 0x66, 0xdf, 0x8d,
- 0x36, 0x6b, 0x5d, 0x56, 0x3e, 0xec, 0xe8, 0xcd, 0xda, 0x0e, 0xa6, 0x8f, 0xa6, 0xd8, 0x5f, 0x1d,
- 0x97, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x4e, 0xa1, 0x75, 0x91, 0x20, 0x00, 0x00,
+ // 2094 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x6f, 0xdc, 0xc6,
+ 0x15, 0x17, 0x57, 0x1f, 0x91, 0x46, 0xf1, 0x47, 0xc6, 0x6a, 0x2c, 0x53, 0xca, 0xae, 0x4c, 0xf7,
+ 0x43, 0x96, 0xdd, 0xa5, 0x24, 0xc3, 0x88, 0x63, 0x57, 0x91, 0xb5, 0x92, 0xec, 0x2c, 0xec, 0xd8,
+ 0x0a, 0x2d, 0xab, 0x85, 0x5b, 0x94, 0xa6, 0xc8, 0xc9, 0x8a, 0x30, 0x97, 0x43, 0x71, 0x66, 0xd7,
+ 0x5e, 0x18, 0x39, 0xa4, 0x87, 0x36, 0xa7, 0x22, 0xe8, 0x07, 0xd0, 0x63, 0x2e, 0x05, 0x7a, 0xe9,
+ 0xa5, 0x87, 0xa2, 0x7f, 0x42, 0x6e, 0x4d, 0x91, 0x4b, 0xd1, 0x83, 0x5b, 0xc8, 0x3d, 0x14, 0x05,
+ 0x5a, 0x14, 0x46, 0x81, 0x9e, 0x0a, 0x14, 0x1c, 0x0e, 0xbf, 0x76, 0xb9, 0xbb, 0xe4, 0xae, 0x7a,
+ 0x5b, 0xce, 0xbc, 0xf7, 0x9b, 0xf7, 0xde, 0xbc, 0xf7, 0xe6, 0xbd, 0x27, 0x01, 0xd9, 0xb4, 0x29,
+ 0x72, 0xf5, 0x03, 0xcd, 0xb4, 0x55, 0x82, 0xf4, 0x86, 0x6b, 0xd2, 0x96, 0xac, 0xeb, 0x4d, 0xd9,
+ 0x71, 0x71, 0xd3, 0x34, 0x90, 0x2b, 0x37, 0x57, 0xe4, 0xc3, 0x06, 0x72, 0x5b, 0x65, 0xc7, 0xc5,
+ 0x14, 0xc3, 0x0b, 0x29, 0x0c, 0x65, 0x5d, 0x6f, 0x96, 0x03, 0x86, 0x72, 0x73, 0x45, 0x9c, 0xaf,
+ 0x61, 0x5c, 0xb3, 0x90, 0xac, 0x39, 0xa6, 0xac, 0xd9, 0x36, 0xa6, 0x1a, 0x35, 0xb1, 0x4d, 0x7c,
+ 0x08, 0x71, 0xa6, 0x86, 0x6b, 0x98, 0xfd, 0x94, 0xbd, 0x5f, 0x7c, 0xb5, 0xc4, 0x79, 0xd8, 0xd7,
+ 0x7e, 0xe3, 0x43, 0x99, 0x9a, 0x75, 0x44, 0xa8, 0x56, 0x77, 0x38, 0xc1, 0x6a, 0x16, 0x51, 0x43,
+ 0x29, 0x7c, 0x9e, 0xe5, 0x6e, 0x3c, 0xcd, 0x15, 0x99, 0x1c, 0x68, 0x2e, 0x32, 0x54, 0x1d, 0xdb,
+ 0xa4, 0x51, 0x0f, 0x39, 0xbe, 0xd6, 0x83, 0xe3, 0xa9, 0xe9, 0x22, 0x4e, 0x36, 0x4f, 0x91, 0x6d,
+ 0x20, 0xb7, 0x6e, 0xda, 0x54, 0xd6, 0xdd, 0x96, 0x43, 0xb1, 0xfc, 0x04, 0xb5, 0x02, 0x0d, 0xcf,
+ 0xe9, 0x98, 0xd4, 0x31, 0x51, 0x7d, 0x25, 0xfd, 0x0f, 0x7f, 0x4b, 0xba, 0x06, 0xe6, 0x3e, 0xf0,
+ 0xcc, 0xb9, 0xc9, 0x8f, 0xbd, 0x8d, 0x6c, 0x44, 0x4c, 0xa2, 0xa0, 0xc3, 0x06, 0x22, 0x14, 0x9e,
+ 0x03, 0x93, 0xfe, 0xd9, 0xa6, 0x31, 0x2b, 0x2c, 0x08, 0x8b, 0x53, 0xca, 0x6b, 0xec, 0xbb, 0x6a,
+ 0x48, 0xcf, 0xc1, 0x7c, 0x3a, 0x27, 0x71, 0xb0, 0x4d, 0x10, 0xfc, 0x2e, 0x38, 0x51, 0xf3, 0x97,
+ 0x54, 0x42, 0x35, 0x8a, 0x18, 0xff, 0xf4, 0xea, 0x72, 0xb9, 0xdb, 0x8d, 0x35, 0x57, 0xca, 0x6d,
+ 0x58, 0x0f, 0x3c, 0xbe, 0xca, 0xd8, 0xe7, 0x2f, 0x4a, 0x23, 0xca, 0xeb, 0xb5, 0xd8, 0x9a, 0x34,
+ 0x0f, 0xc4, 0xc4, 0xe1, 0x9b, 0x1e, 0x5c, 0x20, 0xb5, 0xa4, 0xb5, 0x29, 0x15, 0xec, 0x72, 0xc9,
+ 0x2a, 0x60, 0x82, 0x1d, 0x4f, 0x66, 0x85, 0x85, 0xd1, 0xc5, 0xe9, 0xd5, 0xa5, 0x72, 0x06, 0x27,
+ 0x2a, 0x33, 0x10, 0x85, 0x73, 0x4a, 0x17, 0xc1, 0x37, 0x3a, 0x8f, 0x78, 0x40, 0x35, 0x97, 0xee,
+ 0xb8, 0xd8, 0xc1, 0x44, 0xb3, 0x42, 0x69, 0x3e, 0x11, 0xc0, 0x62, 0x7f, 0x5a, 0x2e, 0xdb, 0xf7,
+ 0xc0, 0x94, 0x13, 0x2c, 0x72, 0x8b, 0xbd, 0x9b, 0x4d, 0x3c, 0x0e, 0xbe, 0x61, 0x18, 0xa6, 0xe7,
+ 0xdd, 0x11, 0x74, 0x04, 0x28, 0x2d, 0x82, 0xaf, 0xa7, 0x49, 0x82, 0x9d, 0x0e, 0xa1, 0x7f, 0x28,
+ 0xa4, 0x2b, 0x98, 0x20, 0x0d, 0x6f, 0xba, 0x43, 0xe6, 0xb5, 0x5c, 0x32, 0x2b, 0xa8, 0x8e, 0x9b,
+ 0x9a, 0x95, 0x2a, 0xf2, 0x2f, 0x0a, 0x60, 0x9c, 0x9d, 0xdd, 0xc3, 0x17, 0xe1, 0x1c, 0x98, 0xd2,
+ 0x2d, 0x13, 0xd9, 0xd4, 0xdb, 0x2b, 0xb0, 0xbd, 0x49, 0x7f, 0xa1, 0x6a, 0xc0, 0x33, 0x60, 0x9c,
+ 0x62, 0x47, 0xbd, 0x37, 0x3b, 0xba, 0x20, 0x2c, 0x9e, 0x50, 0xc6, 0x28, 0x76, 0xee, 0xc1, 0x25,
+ 0x00, 0xeb, 0xa6, 0xad, 0x3a, 0xf8, 0x29, 0x72, 0x55, 0xd3, 0x56, 0x7d, 0x8a, 0xb1, 0x05, 0x61,
+ 0x71, 0x54, 0x39, 0x59, 0x37, 0xed, 0x1d, 0x6f, 0xa3, 0x6a, 0xef, 0x7a, 0xb4, 0xcb, 0x60, 0xa6,
+ 0xa9, 0x59, 0xa6, 0xa1, 0x51, 0xec, 0x12, 0xce, 0xa2, 0x6b, 0xce, 0xec, 0x38, 0xc3, 0x83, 0xd1,
+ 0x1e, 0x63, 0xda, 0xd4, 0x1c, 0xb8, 0x04, 0xde, 0x08, 0x57, 0x55, 0x82, 0x28, 0x23, 0x9f, 0x60,
+ 0xe4, 0xa7, 0xc2, 0x8d, 0x07, 0x88, 0x7a, 0xb4, 0xf3, 0x60, 0x4a, 0xb3, 0x2c, 0xfc, 0xd4, 0x32,
+ 0x09, 0x9d, 0x7d, 0x6d, 0x61, 0x74, 0x71, 0x4a, 0x89, 0x16, 0xa0, 0x08, 0x26, 0x0d, 0x64, 0xb7,
+ 0xd8, 0xe6, 0x24, 0xdb, 0x0c, 0xbf, 0xa5, 0x1f, 0x09, 0xe0, 0x3c, 0xbb, 0xa3, 0xbd, 0x00, 0x32,
+ 0xe6, 0x04, 0x6e, 0xff, 0x10, 0x86, 0x6b, 0xe0, 0x74, 0x70, 0x1d, 0xaa, 0x66, 0x18, 0x2e, 0x22,
+ 0xc4, 0xb7, 0x5e, 0x05, 0xbe, 0x7a, 0x51, 0x3a, 0xd9, 0xd2, 0xea, 0xd6, 0x75, 0x89, 0x6f, 0x48,
+ 0xca, 0xa9, 0x80, 0x76, 0xc3, 0x5f, 0xb9, 0x3e, 0xf9, 0xc9, 0x67, 0xa5, 0x91, 0xbf, 0x7d, 0x56,
+ 0x1a, 0x91, 0xee, 0x03, 0xa9, 0x97, 0x20, 0xdc, 0x4f, 0x2e, 0x82, 0xd3, 0x41, 0x76, 0x0b, 0x8f,
+ 0xf3, 0x25, 0x3a, 0xa5, 0xc7, 0xe8, 0xbd, 0xc3, 0x3a, 0x55, 0xdb, 0x89, 0x1d, 0x9e, 0x4d, 0xb5,
+ 0x8e, 0xb3, 0x7a, 0xa8, 0xd6, 0x76, 0x7e, 0x2f, 0xd5, 0x92, 0x82, 0x44, 0xaa, 0x75, 0x58, 0x92,
+ 0xab, 0xd6, 0x66, 0x35, 0x69, 0x0e, 0x9c, 0x63, 0x80, 0xbb, 0x07, 0x2e, 0xa6, 0xd4, 0x42, 0x2c,
+ 0xa1, 0x05, 0x61, 0xf7, 0x07, 0x81, 0x27, 0xb6, 0xb6, 0x5d, 0x7e, 0x4c, 0x09, 0x4c, 0x13, 0x4b,
+ 0x23, 0x07, 0x6a, 0x1d, 0x51, 0xe4, 0xb2, 0x13, 0x46, 0x15, 0xc0, 0x96, 0xde, 0xf7, 0x56, 0xe0,
+ 0x2a, 0xf8, 0x4a, 0x8c, 0x40, 0x65, 0x7e, 0xa4, 0xd9, 0x3a, 0x62, 0xba, 0x8f, 0x2a, 0x67, 0x22,
+ 0xd2, 0x8d, 0x60, 0x0b, 0x7e, 0x1f, 0xcc, 0xda, 0xe8, 0x19, 0x55, 0x5d, 0xe4, 0x58, 0xc8, 0x36,
+ 0xc9, 0x81, 0xaa, 0x6b, 0xb6, 0xe1, 0x29, 0x8b, 0x58, 0xc8, 0x4c, 0xaf, 0x8a, 0x65, 0xff, 0x31,
+ 0x2c, 0x07, 0x8f, 0x61, 0x79, 0x37, 0x78, 0x0c, 0x2b, 0x93, 0x5e, 0x76, 0xfe, 0xf4, 0xcf, 0x25,
+ 0x41, 0x79, 0xd3, 0x43, 0x51, 0x02, 0x90, 0xcd, 0x00, 0x43, 0xba, 0x0c, 0x96, 0x98, 0x4a, 0x0a,
+ 0xaa, 0x99, 0x84, 0x22, 0x17, 0x19, 0x51, 0xdc, 0x3f, 0xd5, 0x5c, 0x63, 0x0b, 0xd9, 0xb8, 0x1e,
+ 0x26, 0x9e, 0x6d, 0x70, 0x29, 0x13, 0x35, 0xb7, 0xc8, 0x9b, 0x60, 0xc2, 0x60, 0x2b, 0x2c, 0x97,
+ 0x4f, 0x29, 0xfc, 0x4b, 0x2a, 0xf2, 0xd7, 0xc9, 0xcf, 0x29, 0xc8, 0x60, 0x29, 0xa4, 0xba, 0x15,
+ 0x1e, 0xf3, 0xb1, 0x00, 0xde, 0xea, 0x42, 0xc0, 0x91, 0x1f, 0x83, 0x93, 0x4e, 0x7c, 0x2f, 0x78,
+ 0x2d, 0x56, 0x33, 0xa5, 0xb6, 0x04, 0x2c, 0x7f, 0xc2, 0xda, 0xf0, 0xa4, 0x2a, 0x38, 0x91, 0x20,
+ 0x83, 0xb3, 0x80, 0xfb, 0xef, 0x56, 0xd2, 0x9d, 0xb7, 0x60, 0x11, 0x80, 0x20, 0x25, 0x56, 0xb7,
+ 0xd8, 0x65, 0x8e, 0x29, 0xb1, 0x15, 0xe9, 0x2e, 0x90, 0x99, 0x36, 0x1b, 0x96, 0xb5, 0xa3, 0x99,
+ 0x2e, 0xd9, 0xd3, 0xac, 0x4d, 0x6c, 0x7b, 0x2e, 0x57, 0x49, 0x66, 0xf0, 0xea, 0x56, 0x86, 0xa7,
+ 0xfd, 0x97, 0x02, 0x58, 0xce, 0x0e, 0xc7, 0xed, 0x75, 0x08, 0xde, 0x70, 0x34, 0xd3, 0x55, 0x9b,
+ 0x9a, 0xe5, 0x15, 0x31, 0x2c, 0x0c, 0xb8, 0xc9, 0x6e, 0x65, 0x33, 0x99, 0x66, 0xba, 0xd1, 0x41,
+ 0x61, 0x98, 0xd9, 0x91, 0x03, 0x9c, 0x74, 0x12, 0x24, 0xd2, 0xbf, 0x05, 0x70, 0xbe, 0x2f, 0x17,
+ 0xbc, 0xd5, 0x2d, 0x36, 0x2b, 0x73, 0xaf, 0x5e, 0x94, 0xce, 0xfa, 0xa9, 0xa0, 0x9d, 0xa2, 0x33,
+ 0xdd, 0x79, 0x38, 0x5d, 0x52, 0x4a, 0x0c, 0xa7, 0x9d, 0xa2, 0x33, 0xb7, 0xc0, 0x75, 0xf0, 0x7a,
+ 0x48, 0xf5, 0x04, 0xb5, 0x78, 0x8c, 0xcd, 0x97, 0xa3, 0x12, 0xae, 0xec, 0x97, 0x70, 0xe5, 0x9d,
+ 0xc6, 0xbe, 0x65, 0xea, 0x77, 0x50, 0x4b, 0x99, 0x0e, 0x38, 0xee, 0xa0, 0x96, 0x34, 0x03, 0xa0,
+ 0xef, 0xba, 0x9a, 0xab, 0x45, 0x81, 0xf3, 0x18, 0x9c, 0x49, 0xac, 0xf2, 0x6b, 0xa9, 0x82, 0x09,
+ 0x87, 0xad, 0xf0, 0x97, 0xf9, 0x52, 0xc6, 0xbb, 0xf0, 0x58, 0xb8, 0xdf, 0x72, 0x00, 0xe9, 0x36,
+ 0x0f, 0xe4, 0x84, 0x07, 0xdc, 0x77, 0x28, 0x32, 0xaa, 0x76, 0x98, 0x1e, 0xb3, 0x94, 0x8e, 0x87,
+ 0x3c, 0xc6, 0xfb, 0x01, 0x85, 0xf5, 0xda, 0x5b, 0xf1, 0xf7, 0xb7, 0xed, 0xa6, 0x50, 0x10, 0xfa,
+ 0x73, 0xb1, 0x87, 0x38, 0x79, 0x75, 0x88, 0x48, 0x37, 0x40, 0x31, 0x71, 0x64, 0x2e, 0x79, 0x7f,
+ 0x27, 0x80, 0x85, 0x2e, 0xdc, 0xe1, 0xaf, 0xd4, 0xc7, 0x54, 0xc8, 0xfc, 0x98, 0x76, 0x78, 0x45,
+ 0x21, 0xa7, 0x57, 0xc0, 0x19, 0x30, 0xce, 0x4a, 0x13, 0xe6, 0x4f, 0xa3, 0x8a, 0xff, 0xe1, 0x15,
+ 0x9f, 0xa5, 0xae, 0x8a, 0x73, 0xfb, 0x22, 0x00, 0x22, 0xd3, 0xf1, 0x90, 0xdd, 0xce, 0xe4, 0x26,
+ 0xfd, 0x8c, 0xa2, 0xc4, 0x80, 0xa5, 0x43, 0x9e, 0x54, 0x92, 0x55, 0x79, 0x48, 0xfb, 0x9e, 0x46,
+ 0x76, 0x31, 0xff, 0x0a, 0xde, 0xc3, 0x21, 0x8d, 0x2a, 0x69, 0x60, 0x25, 0xc7, 0x91, 0xdc, 0x1c,
+ 0x97, 0x01, 0x0c, 0x6f, 0x22, 0xf0, 0x88, 0xc0, 0xc7, 0xc2, 0x0c, 0xe0, 0x67, 0x3f, 0x83, 0x55,
+ 0x2a, 0x97, 0xd2, 0x6b, 0x9f, 0x4d, 0x5c, 0xaf, 0x9b, 0x84, 0x98, 0xd8, 0x56, 0x62, 0x1a, 0xfd,
+ 0xdf, 0xca, 0x31, 0xa9, 0x06, 0x2e, 0x67, 0x13, 0x84, 0xeb, 0xf9, 0x36, 0x18, 0x73, 0x83, 0xbe,
+ 0x6c, 0xaa, 0x72, 0xc1, 0x0b, 0xf5, 0x3f, 0xbd, 0x28, 0xcd, 0xf9, 0xed, 0x21, 0x31, 0x9e, 0x94,
+ 0x4d, 0x2c, 0xd7, 0x35, 0x7a, 0x50, 0xbe, 0x8b, 0x6a, 0x9a, 0xde, 0xda, 0x42, 0xba, 0xc2, 0x18,
+ 0xa4, 0x35, 0x1e, 0x0d, 0xf7, 0x2d, 0x03, 0x11, 0xfa, 0xd0, 0xd6, 0xb1, 0xfd, 0xa1, 0xe9, 0xd6,
+ 0x91, 0xb1, 0x47, 0xf4, 0x0c, 0xd1, 0xf4, 0xe3, 0xa0, 0xb6, 0x4b, 0xe7, 0xe7, 0xd2, 0x99, 0x00,
+ 0x36, 0x89, 0xae, 0x12, 0x64, 0x1b, 0x6a, 0xd8, 0x7a, 0xf3, 0x1c, 0x76, 0x35, 0x93, 0x73, 0xee,
+ 0x11, 0xfd, 0x01, 0xb2, 0x8d, 0xa8, 0x54, 0xf1, 0xb3, 0xd9, 0xe9, 0x66, 0xdb, 0xba, 0x24, 0x71,
+ 0x7d, 0x2a, 0x16, 0xd6, 0x9f, 0x90, 0x87, 0x36, 0x35, 0xad, 0x7b, 0xe8, 0x19, 0xdd, 0x76, 0xb0,
+ 0x7e, 0x10, 0x64, 0xd7, 0x47, 0x5c, 0xe6, 0x74, 0x1a, 0x2e, 0xf3, 0x55, 0x70, 0x76, 0x9f, 0xed,
+ 0xab, 0x0d, 0x8f, 0x40, 0x65, 0x65, 0x15, 0xf2, 0x48, 0x98, 0xe0, 0x63, 0xca, 0xcc, 0x7e, 0x0a,
+ 0xfb, 0xea, 0xaf, 0xce, 0x83, 0x71, 0x06, 0x0e, 0x8f, 0x04, 0x30, 0x93, 0xd6, 0x54, 0xc3, 0x9b,
+ 0xf9, 0xc3, 0x31, 0xd9, 0xc9, 0x8b, 0x1b, 0x43, 0x20, 0xf8, 0xea, 0x49, 0xdb, 0x3f, 0xf8, 0xf2,
+ 0xaf, 0x3f, 0x2d, 0xac, 0xc3, 0xb5, 0xfe, 0x53, 0x9a, 0x30, 0x80, 0x78, 0xd7, 0x2e, 0x3f, 0x0f,
+ 0xbc, 0xe1, 0x23, 0xf8, 0xa5, 0xc0, 0x5f, 0xaa, 0x64, 0x54, 0xc2, 0xf5, 0xfc, 0x12, 0x26, 0xda,
+ 0x7e, 0xf1, 0xe6, 0xe0, 0x00, 0x5c, 0xc3, 0x77, 0x98, 0x86, 0x57, 0xe0, 0x4a, 0x0e, 0x0d, 0xfd,
+ 0x81, 0x00, 0xfc, 0xb8, 0x00, 0x66, 0xbb, 0x74, 0xf9, 0x04, 0xde, 0x1d, 0x50, 0xb2, 0xd4, 0x81,
+ 0x82, 0xf8, 0xfe, 0x31, 0xa1, 0x71, 0xa5, 0xdf, 0x63, 0x4a, 0x57, 0xe0, 0xcd, 0xbc, 0x4a, 0xab,
+ 0xc4, 0x03, 0x54, 0xc3, 0x5e, 0x1d, 0xfe, 0x57, 0x00, 0x67, 0xd3, 0x87, 0x06, 0x04, 0xde, 0x19,
+ 0x58, 0xe8, 0xce, 0xe9, 0x84, 0x78, 0xf7, 0x78, 0xc0, 0xb8, 0x01, 0x6e, 0x33, 0x03, 0x6c, 0xc0,
+ 0xf5, 0x01, 0x0c, 0x80, 0x9d, 0x98, 0xfe, 0xff, 0x0a, 0xba, 0xb7, 0xd4, 0x3e, 0x18, 0xde, 0xca,
+ 0x2e, 0x75, 0xaf, 0x8e, 0x5e, 0xbc, 0x3d, 0x34, 0x0e, 0x57, 0x7c, 0x83, 0x29, 0x7e, 0x03, 0xbe,
+ 0x93, 0x61, 0xec, 0x1a, 0x8e, 0x33, 0x12, 0x15, 0x6e, 0x8a, 0xca, 0xf1, 0xda, 0x6b, 0x20, 0x95,
+ 0x53, 0x3a, 0xfd, 0x81, 0x54, 0x4e, 0x6b, 0xd4, 0x07, 0x53, 0x39, 0xf1, 0x2a, 0xc3, 0xdf, 0x0b,
+ 0xbc, 0xfe, 0x4e, 0xf4, 0xe8, 0xf0, 0xdd, 0xec, 0x22, 0xa6, 0xb5, 0xfe, 0xe2, 0xfa, 0xc0, 0xfc,
+ 0x5c, 0xb5, 0x6b, 0x4c, 0xb5, 0x55, 0xb8, 0xdc, 0x5f, 0x35, 0xca, 0x01, 0xfc, 0xc9, 0x2c, 0xfc,
+ 0x79, 0x01, 0x5c, 0xc8, 0xd0, 0x74, 0xc3, 0xfb, 0xd9, 0x45, 0xcc, 0xd4, 0xec, 0x8b, 0x3b, 0xc7,
+ 0x07, 0xc8, 0x8d, 0x70, 0x87, 0x19, 0x61, 0x1b, 0x6e, 0xf6, 0x37, 0x82, 0x1b, 0x22, 0x46, 0x3e,
+ 0xed, 0x32, 0x4c, 0xd5, 0x1f, 0x22, 0xc0, 0xbf, 0x77, 0x0c, 0x09, 0x92, 0xbd, 0x2f, 0x81, 0x39,
+ 0x5e, 0xd5, 0x2e, 0x93, 0x08, 0xb1, 0x32, 0x0c, 0x04, 0xd7, 0xba, 0xc2, 0xb4, 0xfe, 0x16, 0xbc,
+ 0xde, 0x5f, 0xeb, 0x60, 0x06, 0xa1, 0xb6, 0x3f, 0x60, 0x3f, 0x2b, 0xf0, 0x31, 0x75, 0x86, 0xa6,
+ 0x1f, 0xee, 0x66, 0x17, 0x3a, 0xfb, 0x48, 0x42, 0x7c, 0x78, 0xcc, 0xa8, 0xdc, 0x3a, 0x37, 0x98,
+ 0x75, 0xae, 0xc2, 0x2b, 0xb9, 0xf3, 0xbb, 0x69, 0xc0, 0xdf, 0x08, 0x60, 0x3a, 0xd6, 0x57, 0xc3,
+ 0xb7, 0x73, 0x5c, 0x57, 0xbc, 0x3f, 0x17, 0xaf, 0xe5, 0x67, 0xe4, 0xf2, 0x2f, 0x33, 0xf9, 0x97,
+ 0xe0, 0x62, 0x86, 0xdb, 0xf5, 0x85, 0xfc, 0x49, 0x10, 0xd0, 0xbd, 0x3b, 0xec, 0x3c, 0x01, 0x9d,
+ 0xa9, 0xe9, 0xcf, 0x13, 0xd0, 0xd9, 0x9a, 0xff, 0x3c, 0xd5, 0x09, 0xf6, 0x40, 0x54, 0xd3, 0x56,
+ 0xa3, 0xa6, 0x33, 0x5e, 0x77, 0xfe, 0xb6, 0x00, 0x2e, 0x66, 0xee, 0x06, 0xe1, 0xc3, 0x41, 0x8b,
+ 0xc9, 0x9e, 0x0d, 0xad, 0xb8, 0x77, 0xdc, 0xb0, 0xdc, 0x4c, 0x8f, 0x98, 0x99, 0x76, 0xa1, 0x92,
+ 0xbb, 0x72, 0x55, 0x1d, 0xe4, 0x46, 0x16, 0x93, 0x9f, 0xb7, 0xb7, 0xa0, 0x1f, 0xc1, 0x5f, 0x17,
+ 0xc0, 0x57, 0xb3, 0x74, 0x96, 0x70, 0x67, 0x88, 0xc2, 0x24, 0xb5, 0x5b, 0x16, 0x3f, 0x38, 0x46,
+ 0x44, 0x6e, 0xa9, 0xc7, 0xcc, 0x52, 0x8f, 0xe0, 0x77, 0xf2, 0x58, 0x2a, 0x84, 0x52, 0xbd, 0x0e,
+ 0x38, 0xe6, 0x55, 0x69, 0xf6, 0xfa, 0x8f, 0xc0, 0x47, 0xfc, 0x69, 0x0d, 0x2e, 0xcc, 0x31, 0x59,
+ 0xe9, 0xd1, 0x60, 0x8b, 0xb7, 0x86, 0x85, 0xc9, 0xff, 0x60, 0x62, 0x86, 0xa3, 0x36, 0x22, 0x20,
+ 0xb5, 0x49, 0xf4, 0x78, 0x88, 0xfd, 0xb3, 0xbd, 0x01, 0x88, 0xe5, 0x9a, 0xcd, 0x61, 0x26, 0x4a,
+ 0x81, 0xd6, 0x5b, 0xc3, 0x81, 0x0c, 0xd1, 0xf1, 0xa4, 0xe7, 0x94, 0x7f, 0x04, 0x57, 0x9d, 0x36,
+ 0x17, 0xc8, 0x73, 0xd5, 0x3d, 0x66, 0x0f, 0x79, 0xae, 0xba, 0xd7, 0x78, 0x22, 0x4f, 0xed, 0xdb,
+ 0x65, 0x8c, 0x51, 0xf9, 0xf6, 0xe7, 0x47, 0x45, 0xe1, 0x8b, 0xa3, 0xa2, 0xf0, 0x97, 0xa3, 0xa2,
+ 0xf0, 0xe9, 0xcb, 0xe2, 0xc8, 0x17, 0x2f, 0x8b, 0x23, 0x7f, 0x7c, 0x59, 0x1c, 0x79, 0xb4, 0x56,
+ 0x33, 0xe9, 0x41, 0x63, 0xbf, 0xac, 0xe3, 0x3a, 0xff, 0x0f, 0x83, 0xd8, 0x29, 0xdf, 0x0c, 0x4f,
+ 0x69, 0x5e, 0x95, 0x9f, 0xb5, 0xd5, 0xa2, 0x2d, 0x07, 0x91, 0xfd, 0x09, 0xf6, 0xa7, 0xa5, 0x2b,
+ 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x26, 0x02, 0x36, 0x87, 0x01, 0x22, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -1974,6 +2062,9 @@ type QueryClient interface {
// 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.
QueryConsumerValidators(ctx context.Context, in *QueryConsumerValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerValidatorsResponse, error)
+ // QueryBlocksUntilNextEpoch returns the number of blocks until the next epoch
+ // starts and validator updates are sent to the consumer chains
+ QueryBlocksUntilNextEpoch(ctx context.Context, in *QueryBlocksUntilNextEpochRequest, opts ...grpc.CallOption) (*QueryBlocksUntilNextEpochResponse, error)
}
type queryClient struct {
@@ -2128,6 +2219,15 @@ func (c *queryClient) QueryConsumerValidators(ctx context.Context, in *QueryCons
return out, nil
}
+func (c *queryClient) QueryBlocksUntilNextEpoch(ctx context.Context, in *QueryBlocksUntilNextEpochRequest, opts ...grpc.CallOption) (*QueryBlocksUntilNextEpochResponse, error) {
+ out := new(QueryBlocksUntilNextEpochResponse)
+ err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryBlocksUntilNextEpoch", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// QueryServer is the server API for Query service.
type QueryServer interface {
// ConsumerGenesis queries the genesis state needed to start a consumer chain
@@ -2175,6 +2275,9 @@ type QueryServer interface {
// 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.
QueryConsumerValidators(context.Context, *QueryConsumerValidatorsRequest) (*QueryConsumerValidatorsResponse, error)
+ // QueryBlocksUntilNextEpoch returns the number of blocks until the next epoch
+ // starts and validator updates are sent to the consumer chains
+ QueryBlocksUntilNextEpoch(context.Context, *QueryBlocksUntilNextEpochRequest) (*QueryBlocksUntilNextEpochResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
@@ -2229,6 +2332,9 @@ func (*UnimplementedQueryServer) QueryOldestUnconfirmedVsc(ctx context.Context,
func (*UnimplementedQueryServer) QueryConsumerValidators(ctx context.Context, req *QueryConsumerValidatorsRequest) (*QueryConsumerValidatorsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerValidators not implemented")
}
+func (*UnimplementedQueryServer) QueryBlocksUntilNextEpoch(ctx context.Context, req *QueryBlocksUntilNextEpochRequest) (*QueryBlocksUntilNextEpochResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method QueryBlocksUntilNextEpoch not implemented")
+}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
@@ -2522,6 +2628,24 @@ func _Query_QueryConsumerValidators_Handler(srv interface{}, ctx context.Context
return interceptor(ctx, in, info, handler)
}
+func _Query_QueryBlocksUntilNextEpoch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(QueryBlocksUntilNextEpochRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).QueryBlocksUntilNextEpoch(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryBlocksUntilNextEpoch",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).QueryBlocksUntilNextEpoch(ctx, req.(*QueryBlocksUntilNextEpochRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "interchain_security.ccv.provider.v1.Query",
HandlerType: (*QueryServer)(nil),
@@ -2590,6 +2714,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{
MethodName: "QueryConsumerValidators",
Handler: _Query_QueryConsumerValidators_Handler,
},
+ {
+ MethodName: "QueryBlocksUntilNextEpoch",
+ Handler: _Query_QueryBlocksUntilNextEpoch_Handler,
+ },
},
Streams: []grpc.StreamDesc{},
Metadata: "interchain_security/ccv/provider/v1/query.proto",
@@ -3800,6 +3928,57 @@ func (m *QueryOldestUnconfirmedVscResponse) MarshalToSizedBuffer(dAtA []byte) (i
return len(dAtA) - i, nil
}
+func (m *QueryBlocksUntilNextEpochRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *QueryBlocksUntilNextEpochRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *QueryBlocksUntilNextEpochRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *QueryBlocksUntilNextEpochResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *QueryBlocksUntilNextEpochResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *QueryBlocksUntilNextEpochResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.BlocksUntilNextEpoch != 0 {
+ i = encodeVarintQuery(dAtA, i, uint64(m.BlocksUntilNextEpoch))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
@@ -4319,6 +4498,27 @@ func (m *QueryOldestUnconfirmedVscResponse) Size() (n int) {
return n
}
+func (m *QueryBlocksUntilNextEpochRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *QueryBlocksUntilNextEpochResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.BlocksUntilNextEpoch != 0 {
+ n += 1 + sovQuery(uint64(m.BlocksUntilNextEpoch))
+ }
+ return n
+}
+
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -7523,6 +7723,125 @@ func (m *QueryOldestUnconfirmedVscResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *QueryBlocksUntilNextEpochRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: QueryBlocksUntilNextEpochRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: QueryBlocksUntilNextEpochRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *QueryBlocksUntilNextEpochResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: QueryBlocksUntilNextEpochResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: QueryBlocksUntilNextEpochResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BlocksUntilNextEpoch", wireType)
+ }
+ m.BlocksUntilNextEpoch = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.BlocksUntilNextEpoch |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
diff --git a/x/ccv/provider/types/query.pb.gw.go b/x/ccv/provider/types/query.pb.gw.go
index 16bb010d71..707242058e 100644
--- a/x/ccv/provider/types/query.pb.gw.go
+++ b/x/ccv/provider/types/query.pb.gw.go
@@ -613,6 +613,24 @@ func local_request_Query_QueryConsumerValidators_0(ctx context.Context, marshale
}
+func request_Query_QueryBlocksUntilNextEpoch_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq QueryBlocksUntilNextEpochRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := client.QueryBlocksUntilNextEpoch(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ return msg, metadata, err
+
+}
+
+func local_request_Query_QueryBlocksUntilNextEpoch_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq QueryBlocksUntilNextEpochRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := server.QueryBlocksUntilNextEpoch(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -987,6 +1005,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
})
+ mux.Handle("GET", pattern_Query_QueryBlocksUntilNextEpoch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_Query_QueryBlocksUntilNextEpoch_0(rctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Query_QueryBlocksUntilNextEpoch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
@@ -1348,6 +1389,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
})
+ mux.Handle("GET", pattern_Query_QueryBlocksUntilNextEpoch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_Query_QueryBlocksUntilNextEpoch_0(rctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Query_QueryBlocksUntilNextEpoch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
@@ -1383,6 +1444,8 @@ var (
pattern_Query_QueryOldestUnconfirmedVsc_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "oldest_unconfirmed_vsc", "chain_id"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_QueryConsumerValidators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "consumer_validators", "chain_id"}, "", runtime.AssumeColonVerbOpt(false)))
+
+ pattern_Query_QueryBlocksUntilNextEpoch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "blocks_until_next_epoch"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
@@ -1417,4 +1480,6 @@ var (
forward_Query_QueryOldestUnconfirmedVsc_0 = runtime.ForwardResponseMessage
forward_Query_QueryConsumerValidators_0 = runtime.ForwardResponseMessage
+
+ forward_Query_QueryBlocksUntilNextEpoch_0 = runtime.ForwardResponseMessage
)
From 56c9bf3aed0d9bdb5ae7e4eef0068b960c251af0 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 26 Jul 2024 16:58:55 +0200
Subject: [PATCH 02/11] Fix epoch end in relay
---
x/ccv/provider/keeper/grpc_query.go | 2 +-
x/ccv/provider/keeper/relay.go | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go
index 17ba6150dc..982352f578 100644
--- a/x/ccv/provider/keeper/grpc_query.go
+++ b/x/ccv/provider/keeper/grpc_query.go
@@ -495,5 +495,5 @@ func (k Keeper) QueryBlocksUntilNextEpoch(goCtx context.Context, req *types.Quer
// Calculate the blocks until the next epoch
blocksUntilNextEpoch := k.BlocksUntilNextEpoch(ctx)
- return &types.QueryBlocksUntilNextEpochResponse{BlocksUntilNextEpoch: blocksUntilNextEpoch}, nil
+ return &types.QueryBlocksUntilNextEpochResponse{BlocksUntilNextEpoch: uint64(blocksUntilNextEpoch)}, nil
}
diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go
index fbc4f2acd4..617f41ccfb 100644
--- a/x/ccv/provider/keeper/relay.go
+++ b/x/ccv/provider/keeper/relay.go
@@ -149,7 +149,7 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) {
// notify the staking module to complete all matured unbonding ops
k.completeMaturedUnbondingOps(ctx)
- if k.BlocksUntilNextEpoch(ctx) == 0 {
+ if k.BlocksUntilNextEpoch(ctx) == k.GetBlocksPerEpoch(ctx) {
// only queue and send VSCPackets at the boundaries of an epoch
// collect validator updates
@@ -164,9 +164,9 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) {
// BlocksUntilNextEpoch returns the number of blocks until the next epoch starts
// Returns 0 if the current block is the last block of the epoch
-func (k Keeper) BlocksUntilNextEpoch(ctx sdk.Context) uint64 {
+func (k Keeper) BlocksUntilNextEpoch(ctx sdk.Context) int64 {
epochLength := k.GetBlocksPerEpoch(ctx)
- return uint64(epochLength - ctx.BlockHeight()%epochLength)
+ return int64(epochLength - ctx.BlockHeight()%epochLength)
}
// SendVSCPackets iterates over all registered consumers and sends pending
From 99a64c70254e35bbcd78d7e281309d1d22e55b78 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 26 Jul 2024 17:01:00 +0200
Subject: [PATCH 03/11] Adjust test comment
---
x/ccv/provider/keeper/relay_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go
index 7adbe83263..44000eeac4 100644
--- a/x/ccv/provider/keeper/relay_test.go
+++ b/x/ccv/provider/keeper/relay_test.go
@@ -943,7 +943,7 @@ func TestBlocksUntilNextEpoch(t *testing.T) {
ctx = ctx.WithBlockHeight(5)
require.Equal(t, uint64(5), providerKeeper.BlocksUntilNextEpoch(ctx))
- // with block height of 10 we expect 0 blocks until the next epoch
+ // with block height of 10 we expect 10 blocks until the next epoch, since the last epoch ends with this block
ctx = ctx.WithBlockHeight(10)
require.Equal(t, uint64(10), providerKeeper.BlocksUntilNextEpoch(ctx))
From b9e8cf3b0434ff1b0148ac6b8083cf297c25337a Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 26 Jul 2024 17:02:05 +0200
Subject: [PATCH 04/11] Add changelog entries
---
.../features/provider/2106-query-blocks-until-next-epoch.md | 2 ++
.../provider/2106-query-blocks-until-next-epoch.md | 2 ++
2 files changed, 4 insertions(+)
create mode 100644 .changelog/unreleased/features/provider/2106-query-blocks-until-next-epoch.md
create mode 100644 .changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md
diff --git a/.changelog/unreleased/features/provider/2106-query-blocks-until-next-epoch.md b/.changelog/unreleased/features/provider/2106-query-blocks-until-next-epoch.md
new file mode 100644
index 0000000000..070fa487e9
--- /dev/null
+++ b/.changelog/unreleased/features/provider/2106-query-blocks-until-next-epoch.md
@@ -0,0 +1,2 @@
+- Add a query to get the blocks until the next epoch begins
+ ([\#2106](https://github.com/cosmos/interchain-security/pull/2106))
\ No newline at end of file
diff --git a/.changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md b/.changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md
new file mode 100644
index 0000000000..070fa487e9
--- /dev/null
+++ b/.changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md
@@ -0,0 +1,2 @@
+- Add a query to get the blocks until the next epoch begins
+ ([\#2106](https://github.com/cosmos/interchain-security/pull/2106))
\ No newline at end of file
From 88854c8e724ac328496a86128fde90eb74d0a164 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 26 Jul 2024 17:10:48 +0200
Subject: [PATCH 05/11] Add command to CLI endpoint and document
---
docs/docs/frequently-asked-questions.md | 10 +++++++++-
x/ccv/provider/client/cli/query.go | 1 +
x/ccv/provider/keeper/grpc_query.go | 1 +
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/docs/docs/frequently-asked-questions.md b/docs/docs/frequently-asked-questions.md
index 27623d22f6..0018721af0 100644
--- a/docs/docs/frequently-asked-questions.md
+++ b/docs/docs/frequently-asked-questions.md
@@ -134,4 +134,12 @@ By setting the commission rate ahead of time, they can make sure that they immed
Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consumermodificationproposal).
## Can a Top N consumer chain become Opt-In or vice versa?
-Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consumermodificationproposal).
\ No newline at end of file
+Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consumermodificationproposal).
+
+## How I know when the next validator update will be sent to the consumer chain?
+Validator updates are sent to the consumer chain every `BlocksPerEpoch` blocks.
+To query how many blocks are left until the next epoch starts,
+run the following command:
+```bash
+interchain-security-pd query provider blocks-until-next-epoch
+```
\ No newline at end of file
diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go
index da84252dfc..a7623874eb 100644
--- a/x/ccv/provider/client/cli/query.go
+++ b/x/ccv/provider/client/cli/query.go
@@ -40,6 +40,7 @@ func NewQueryCmd() *cobra.Command {
cmd.AddCommand(CmdConsumerChainsValidatorHasToValidate())
cmd.AddCommand(CmdValidatorConsumerCommissionRate())
cmd.AddCommand(CmdOldestUnconfirmedVsc())
+ cmd.AddCommand(CmdBlocksUntilNextEpoch())
return cmd
}
diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go
index 982352f578..3ac0a4b63e 100644
--- a/x/ccv/provider/keeper/grpc_query.go
+++ b/x/ccv/provider/keeper/grpc_query.go
@@ -489,6 +489,7 @@ func (k Keeper) QueryOldestUnconfirmedVsc(goCtx context.Context, req *types.Quer
return &types.QueryOldestUnconfirmedVscResponse{VscSendTimestamp: ts}, nil
}
+// QueryBlocksUntilNextEpoch returns the number of blocks until the next epoch
func (k Keeper) QueryBlocksUntilNextEpoch(goCtx context.Context, req *types.QueryBlocksUntilNextEpochRequest) (*types.QueryBlocksUntilNextEpochResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
From 062dad652e7979433c49b5a5b0a06dd2cfd108b7 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 26 Jul 2024 17:12:13 +0200
Subject: [PATCH 06/11] Fix typo in doc
---
x/ccv/provider/client/cli/query.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go
index a7623874eb..4096d06ea5 100644
--- a/x/ccv/provider/client/cli/query.go
+++ b/x/ccv/provider/client/cli/query.go
@@ -601,7 +601,7 @@ func CmdOldestUnconfirmedVsc() *cobra.Command {
func CmdBlocksUntilNextEpoch() *cobra.Command {
cmd := &cobra.Command{
Use: "blocks-until-next-epoch",
- Short: "Query the number of blocks until the next epoch begins and validator updates are sent to consumer chain",
+ Short: "Query the number of blocks until the next epoch begins and validator updates are sent to consumer chains",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
From 36565c97cd54a1cd319482511f1407a8152998fc Mon Sep 17 00:00:00 2001
From: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com>
Date: Fri, 26 Jul 2024 20:13:19 +0200
Subject: [PATCH 07/11] Update x/ccv/provider/keeper/relay.go
Co-authored-by: insumity
---
x/ccv/provider/keeper/relay.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go
index 617f41ccfb..18af14a5f2 100644
--- a/x/ccv/provider/keeper/relay.go
+++ b/x/ccv/provider/keeper/relay.go
@@ -166,7 +166,7 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) {
// Returns 0 if the current block is the last block of the epoch
func (k Keeper) BlocksUntilNextEpoch(ctx sdk.Context) int64 {
epochLength := k.GetBlocksPerEpoch(ctx)
- return int64(epochLength - ctx.BlockHeight()%epochLength)
+ return int64(epochLength - (ctx.BlockHeight()%epochLength))
}
// SendVSCPackets iterates over all registered consumers and sends pending
From 27774e193f8fdfd3e308eaadc2abfad498d52a25 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com>
Date: Fri, 26 Jul 2024 20:14:58 +0200
Subject: [PATCH 08/11] Delete
.changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md
---
.../provider/2106-query-blocks-until-next-epoch.md | 2 --
1 file changed, 2 deletions(-)
delete mode 100644 .changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md
diff --git a/.changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md b/.changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md
deleted file mode 100644
index 070fa487e9..0000000000
--- a/.changelog/unreleased/state-breaking/provider/2106-query-blocks-until-next-epoch.md
+++ /dev/null
@@ -1,2 +0,0 @@
-- Add a query to get the blocks until the next epoch begins
- ([\#2106](https://github.com/cosmos/interchain-security/pull/2106))
\ No newline at end of file
From c60d606fd9c57c12a3864f982540cfd1257699bf Mon Sep 17 00:00:00 2001
From: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com>
Date: Fri, 26 Jul 2024 20:16:56 +0200
Subject: [PATCH 09/11] Update docs/docs/frequently-asked-questions.md
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
docs/docs/frequently-asked-questions.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/docs/frequently-asked-questions.md b/docs/docs/frequently-asked-questions.md
index 0018721af0..03f66ecd3d 100644
--- a/docs/docs/frequently-asked-questions.md
+++ b/docs/docs/frequently-asked-questions.md
@@ -136,7 +136,7 @@ Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consu
## Can a Top N consumer chain become Opt-In or vice versa?
Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consumermodificationproposal).
-## How I know when the next validator update will be sent to the consumer chain?
+## How do I know when the next validator update will be sent to the consumer chain?
Validator updates are sent to the consumer chain every `BlocksPerEpoch` blocks.
To query how many blocks are left until the next epoch starts,
run the following command:
From 23cf6bf0bf54ed4b8965d69d61c8ec3f043db8a8 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Mon, 29 Jul 2024 09:55:39 +0200
Subject: [PATCH 10/11] Clarify relaying delay for VSCPackets
---
docs/docs/frequently-asked-questions.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/docs/docs/frequently-asked-questions.md b/docs/docs/frequently-asked-questions.md
index 03f66ecd3d..2183f74c26 100644
--- a/docs/docs/frequently-asked-questions.md
+++ b/docs/docs/frequently-asked-questions.md
@@ -138,6 +138,9 @@ Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consu
## How do I know when the next validator update will be sent to the consumer chain?
Validator updates are sent to the consumer chain every `BlocksPerEpoch` blocks.
+Keep in mind that depending on the status of relayers between the Hub and the consumer chain,
+it might take a while for the validator update to be processed and applied on the consumer chain.
+
To query how many blocks are left until the next epoch starts,
run the following command:
```bash
From cdef43de52c9088913d83d4276938e003858305d Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Mon, 29 Jul 2024 10:52:12 +0200
Subject: [PATCH 11/11] Change BlocksUntilNextEpoch to return 0 on first block
of epoch
---
x/ccv/provider/keeper/relay.go | 14 ++++++++++----
x/ccv/provider/keeper/relay_test.go | 19 ++++++++++++++-----
2 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go
index 18af14a5f2..9e4466765a 100644
--- a/x/ccv/provider/keeper/relay.go
+++ b/x/ccv/provider/keeper/relay.go
@@ -149,7 +149,7 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) {
// notify the staking module to complete all matured unbonding ops
k.completeMaturedUnbondingOps(ctx)
- if k.BlocksUntilNextEpoch(ctx) == k.GetBlocksPerEpoch(ctx) {
+ if k.BlocksUntilNextEpoch(ctx) == 0 {
// only queue and send VSCPackets at the boundaries of an epoch
// collect validator updates
@@ -163,10 +163,16 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) {
}
// BlocksUntilNextEpoch returns the number of blocks until the next epoch starts
-// Returns 0 if the current block is the last block of the epoch
+// Returns 0 if VSCPackets are sent in the current block,
+// which is done in the first block of each epoch.
func (k Keeper) BlocksUntilNextEpoch(ctx sdk.Context) int64 {
- epochLength := k.GetBlocksPerEpoch(ctx)
- return int64(epochLength - (ctx.BlockHeight()%epochLength))
+ blocksSinceEpochStart := ctx.BlockHeight() % k.GetBlocksPerEpoch(ctx)
+
+ if blocksSinceEpochStart == 0 {
+ return 0
+ } else {
+ return int64(k.GetBlocksPerEpoch(ctx) - blocksSinceEpochStart)
+ }
}
// SendVSCPackets iterates over all registered consumers and sends pending
diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go
index 44000eeac4..25fdedfa56 100644
--- a/x/ccv/provider/keeper/relay_test.go
+++ b/x/ccv/provider/keeper/relay_test.go
@@ -937,17 +937,26 @@ func TestBlocksUntilNextEpoch(t *testing.T) {
// with block height of 1 we expect 9 blocks until the next epoch
ctx = ctx.WithBlockHeight(1)
- require.Equal(t, uint64(9), providerKeeper.BlocksUntilNextEpoch(ctx))
+ require.Equal(t, int64(9), providerKeeper.BlocksUntilNextEpoch(ctx))
// with block height of 5 we expect 5 blocks until the next epoch
ctx = ctx.WithBlockHeight(5)
- require.Equal(t, uint64(5), providerKeeper.BlocksUntilNextEpoch(ctx))
+ require.Equal(t, int64(5), providerKeeper.BlocksUntilNextEpoch(ctx))
- // with block height of 10 we expect 10 blocks until the next epoch, since the last epoch ends with this block
+ // with block height of 10 we expect 0 blocks until the next epoch, since
+ // this epoch is the one where we send the VSC packet
ctx = ctx.WithBlockHeight(10)
- require.Equal(t, uint64(10), providerKeeper.BlocksUntilNextEpoch(ctx))
+ require.Equal(t, int64(0), providerKeeper.BlocksUntilNextEpoch(ctx))
+
+ // with block height of 11 we expect 9 blocks until the next epoch
+ ctx = ctx.WithBlockHeight(11)
+ require.Equal(t, int64(9), providerKeeper.BlocksUntilNextEpoch(ctx))
// with block height of 15 we expect 5 blocks until the next epoch
ctx = ctx.WithBlockHeight(15)
- require.Equal(t, uint64(5), providerKeeper.BlocksUntilNextEpoch(ctx))
+ require.Equal(t, int64(5), providerKeeper.BlocksUntilNextEpoch(ctx))
+
+ // with block height of 19 we expect 1 block until the next epoch
+ ctx = ctx.WithBlockHeight(19)
+ require.Equal(t, int64(1), providerKeeper.BlocksUntilNextEpoch(ctx))
}