diff --git a/CHANGELOG.md b/CHANGELOG.md index fe8d4b2328df..c22d21ca3387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,7 +51,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (query) [#14468](https://github.com/cosmos/cosmos-sdk/pull/14468) Implement pagination for collections. * (x/bank) [#14045](https://github.com/cosmos/cosmos-sdk/pull/14045) Add CLI command `spendable-balances`, which also accepts the flag `--denom`. * (x/slashing, x/staking) [#14363](https://github.com/cosmos/cosmos-sdk/pull/14363) Add the infraction a validator commited type as an argument to a `SlashWithInfractionReason` keeper method. -* (client) [#13867](https://github.com/cosmos/cosmos-sdk/pull/13867/) Wire AutoCLI commands with SimApp. * (x/distribution) [#14322](https://github.com/cosmos/cosmos-sdk/pull/14322) Introduce a new gRPC message handler, `DepositValidatorRewardsPool`, that allows explicit funding of a validator's reward pool. * (x/evidence) [#13740](https://github.com/cosmos/cosmos-sdk/pull/13740) Add new proto field `hash` of type `string` to `QueryEvidenceRequest` which helps to decode the hash properly while using query API. * (core) [#13306](https://github.com/cosmos/cosmos-sdk/pull/13306) Add a `FormatCoins` function to in `core/coins` to format sdk Coins following the Value Renderers spec. @@ -82,6 +81,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* (x/auth) [#14758](https://github.com/cosmos/cosmos-sdk/pull/14758) Allow transaction event queries to directly passed to Tendermint, which will allow for full query operator support, e.g. `>`. * (server) [#15041](https://github.com/cosmos/cosmos-sdk/pull/15041) Remove unnecessary sleeps from gRPC and API server initiation. The servers will start and accept requests as soon as they're ready. * (x/staking) [#14864](https://github.com/cosmos/cosmos-sdk/pull/14864) `create-validator` CLI command now takes a json file as an arg instead of having a bunch of required flags to it. * (cli) [#14659](https://github.com/cosmos/cosmos-sdk/pull/14659) Added ability to query blocks by either height/hash `simd q block --type=height|hash `. @@ -182,6 +182,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* (x/auth) [#14758](https://github.com/cosmos/cosmos-sdk/pull/14758) Refactor transaction searching: + * Refactor `QueryTxsByEvents` to accept a `query` of type `string` instead of `events` of type `[]string` + * Pass `prove=false` to Tendermint's `TxSearch` RPC method + * Refactor CLI methods to accept `--query` flag instead of `--events` * (server) [#15041](https://github.com/cosmos/cosmos-sdk/pull/15041) Refactor how gRPC and API servers are started to remove unnecessary sleeps: * Remove `ServerStartTime` constant. * Rename `WaitForQuitSignals` to `ListenForQuitSignals`. Note, this function is no longer blocking. Thus the caller is expected to provide a `context.CancelFunc` which indicates that when a signal is caught, that any spawned processes can gracefully exit. diff --git a/api/cosmos/tx/v1beta1/service.pulsar.go b/api/cosmos/tx/v1beta1/service.pulsar.go index 5722e70aaa73..0a5e51f8e3d5 100644 --- a/api/cosmos/tx/v1beta1/service.pulsar.go +++ b/api/cosmos/tx/v1beta1/service.pulsar.go @@ -69,6 +69,7 @@ var ( fd_GetTxsEventRequest_order_by protoreflect.FieldDescriptor fd_GetTxsEventRequest_page protoreflect.FieldDescriptor fd_GetTxsEventRequest_limit protoreflect.FieldDescriptor + fd_GetTxsEventRequest_query protoreflect.FieldDescriptor ) func init() { @@ -79,6 +80,7 @@ func init() { fd_GetTxsEventRequest_order_by = md_GetTxsEventRequest.Fields().ByName("order_by") fd_GetTxsEventRequest_page = md_GetTxsEventRequest.Fields().ByName("page") fd_GetTxsEventRequest_limit = md_GetTxsEventRequest.Fields().ByName("limit") + fd_GetTxsEventRequest_query = md_GetTxsEventRequest.Fields().ByName("query") } var _ protoreflect.Message = (*fastReflection_GetTxsEventRequest)(nil) @@ -176,6 +178,12 @@ func (x *fastReflection_GetTxsEventRequest) Range(f func(protoreflect.FieldDescr return } } + if x.Query != "" { + value := protoreflect.ValueOfString(x.Query) + if !f(fd_GetTxsEventRequest_query, value) { + return + } + } } // Has reports whether a field is populated. @@ -201,6 +209,8 @@ func (x *fastReflection_GetTxsEventRequest) Has(fd protoreflect.FieldDescriptor) return x.Page != uint64(0) case "cosmos.tx.v1beta1.GetTxsEventRequest.limit": return x.Limit != uint64(0) + case "cosmos.tx.v1beta1.GetTxsEventRequest.query": + return x.Query != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.tx.v1beta1.GetTxsEventRequest")) @@ -227,6 +237,8 @@ func (x *fastReflection_GetTxsEventRequest) Clear(fd protoreflect.FieldDescripto x.Page = uint64(0) case "cosmos.tx.v1beta1.GetTxsEventRequest.limit": x.Limit = uint64(0) + case "cosmos.tx.v1beta1.GetTxsEventRequest.query": + x.Query = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.tx.v1beta1.GetTxsEventRequest")) @@ -261,6 +273,9 @@ func (x *fastReflection_GetTxsEventRequest) Get(descriptor protoreflect.FieldDes case "cosmos.tx.v1beta1.GetTxsEventRequest.limit": value := x.Limit return protoreflect.ValueOfUint64(value) + case "cosmos.tx.v1beta1.GetTxsEventRequest.query": + value := x.Query + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.tx.v1beta1.GetTxsEventRequest")) @@ -293,6 +308,8 @@ func (x *fastReflection_GetTxsEventRequest) Set(fd protoreflect.FieldDescriptor, x.Page = value.Uint() case "cosmos.tx.v1beta1.GetTxsEventRequest.limit": x.Limit = value.Uint() + case "cosmos.tx.v1beta1.GetTxsEventRequest.query": + x.Query = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.tx.v1beta1.GetTxsEventRequest")) @@ -330,6 +347,8 @@ func (x *fastReflection_GetTxsEventRequest) Mutable(fd protoreflect.FieldDescrip panic(fmt.Errorf("field page of message cosmos.tx.v1beta1.GetTxsEventRequest is not mutable")) case "cosmos.tx.v1beta1.GetTxsEventRequest.limit": panic(fmt.Errorf("field limit of message cosmos.tx.v1beta1.GetTxsEventRequest is not mutable")) + case "cosmos.tx.v1beta1.GetTxsEventRequest.query": + panic(fmt.Errorf("field query of message cosmos.tx.v1beta1.GetTxsEventRequest is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.tx.v1beta1.GetTxsEventRequest")) @@ -355,6 +374,8 @@ func (x *fastReflection_GetTxsEventRequest) NewField(fd protoreflect.FieldDescri return protoreflect.ValueOfUint64(uint64(0)) case "cosmos.tx.v1beta1.GetTxsEventRequest.limit": return protoreflect.ValueOfUint64(uint64(0)) + case "cosmos.tx.v1beta1.GetTxsEventRequest.query": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.tx.v1beta1.GetTxsEventRequest")) @@ -443,6 +464,10 @@ func (x *fastReflection_GetTxsEventRequest) ProtoMethods() *protoiface.Methods { if x.Limit != 0 { n += 1 + runtime.Sov(uint64(x.Limit)) } + l = len(x.Query) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -472,6 +497,13 @@ func (x *fastReflection_GetTxsEventRequest) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.Query) > 0 { + i -= len(x.Query) + copy(dAtA[i:], x.Query) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Query))) + i-- + dAtA[i] = 0x32 + } if x.Limit != 0 { i = runtime.EncodeVarint(dAtA, i, uint64(x.Limit)) i-- @@ -684,6 +716,38 @@ func (x *fastReflection_GetTxsEventRequest) ProtoMethods() *protoiface.Methods { break } } + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -8961,7 +9025,8 @@ const ( type OrderBy int32 const ( - // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. + // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults + // to ASC in this case. OrderBy_ORDER_BY_UNSPECIFIED OrderBy = 0 // ORDER_BY_ASC defines ascending order OrderBy_ORDER_BY_ASC OrderBy = 1 @@ -9010,7 +9075,8 @@ func (OrderBy) EnumDescriptor() ([]byte, []int) { return file_cosmos_tx_v1beta1_service_proto_rawDescGZIP(), []int{0} } -// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. +// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC +// method. type BroadcastMode int32 const ( @@ -9021,11 +9087,11 @@ const ( // // Deprecated: Do not use. BroadcastMode_BROADCAST_MODE_BLOCK BroadcastMode = 1 - // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for - // a CheckTx execution response only. + // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits + // for a CheckTx execution response only. BroadcastMode_BROADCAST_MODE_SYNC BroadcastMode = 2 - // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns - // immediately. + // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client + // returns immediately. BroadcastMode_BROADCAST_MODE_ASYNC BroadcastMode = 3 ) @@ -9080,6 +9146,8 @@ type GetTxsEventRequest struct { unknownFields protoimpl.UnknownFields // events is the list of transaction event type. + // Deprecated post v0.47.x: use query instead, which should contain a valid + // events query. Events []string `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` // pagination defines a pagination for the request. // Deprecated post v0.46.x: use page and limit instead. @@ -9087,11 +9155,15 @@ type GetTxsEventRequest struct { // Deprecated: Do not use. Pagination *v1beta1.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` OrderBy OrderBy `protobuf:"varint,3,opt,name=order_by,json=orderBy,proto3,enum=cosmos.tx.v1beta1.OrderBy" json:"order_by,omitempty"` - // page is the page number to query, starts at 1. If not provided, will default to first page. + // page is the page number to query, starts at 1. If not provided, will + // default to first page. Page uint64 `protobuf:"varint,4,opt,name=page,proto3" json:"page,omitempty"` // limit is the total number of results to be returned in the result page. // If left empty it will default to a value to be set by each app. Limit uint64 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"` + // query defines the transaction event query that is proxied to Tendermint's + // TxSearch RPC method. The query must be valid. + Query string `protobuf:"bytes,6,opt,name=query,proto3" json:"query,omitempty"` } func (x *GetTxsEventRequest) Reset() { @@ -9150,6 +9222,13 @@ func (x *GetTxsEventRequest) GetLimit() uint64 { return 0 } +func (x *GetTxsEventRequest) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + // GetTxsEventResponse is the response type for the Service.TxsByEvents // RPC method. type GetTxsEventResponse struct { @@ -9536,7 +9615,8 @@ func (x *GetBlockWithTxsRequest) GetPagination() *v1beta1.PageRequest { return nil } -// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method. +// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs +// method. // // Since: cosmos-sdk 0.45.2 type GetBlockWithTxsResponse struct { @@ -9934,7 +10014,7 @@ var file_cosmos_tx_v1beta1_service_proto_rawDesc = []byte{ 0x1c, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x01, 0x0a, 0x12, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xef, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x78, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x70, 0x61, @@ -9948,209 +10028,210 @@ var file_cosmos_tx_v1beta1_service_proto_rawDesc = []byte{ 0x65, 0x72, 0x42, 0x79, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0xea, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x54, - 0x78, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x27, 0x0a, 0x03, 0x74, 0x78, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, + 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xea, 0x01, + 0x0a, 0x13, 0x47, 0x65, 0x74, 0x54, 0x78, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x03, 0x74, 0x78, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x03, 0x74, 0x78, 0x73, 0x12, 0x47, + 0x0a, 0x0c, 0x74, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0b, 0x74, 0x78, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x65, 0x0a, 0x12, 0x42, 0x72, + 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x04, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x72, + 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x22, 0x5c, 0x0a, 0x13, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x78, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x74, 0x78, 0x5f, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, 0x69, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x74, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x57, 0x0a, 0x0f, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x29, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x54, 0x78, 0x42, 0x02, 0x18, 0x01, 0x52, 0x02, 0x74, 0x78, 0x12, 0x19, 0x0a, + 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, + 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, + 0x08, 0x67, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, + 0x63, 0x69, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x61, 0x73, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x07, 0x67, 0x61, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x22, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x54, 0x78, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x7d, 0x0a, 0x0d, 0x47, 0x65, 0x74, + 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x02, 0x74, 0x78, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x02, 0x74, + 0x78, 0x12, 0x45, 0x0a, 0x0b, 0x74, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x74, 0x78, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x78, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x54, 0x78, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0xf0, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x57, + 0x69, 0x74, 0x68, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, + 0x0a, 0x03, 0x74, 0x78, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x54, 0x78, 0x52, 0x03, 0x74, 0x78, 0x73, 0x12, 0x34, 0x0a, 0x08, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x49, 0x44, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x64, 0x12, 0x2d, 0x0a, + 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x47, 0x0a, 0x0a, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x0f, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x22, 0x39, 0x0a, 0x10, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x02, 0x74, 0x78, 0x22, 0x38, + 0x0a, 0x0f, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x25, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x54, 0x78, 0x52, 0x02, 0x74, 0x78, 0x22, 0x2d, 0x0a, 0x10, 0x54, 0x78, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x35, 0x0a, 0x14, 0x54, 0x78, 0x45, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x3a, + 0x0a, 0x15, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6d, 0x69, 0x6e, 0x6f, + 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x61, + 0x6d, 0x69, 0x6e, 0x6f, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, 0x39, 0x0a, 0x14, 0x54, 0x78, + 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x5f, 0x62, 0x69, 0x6e, 0x61, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x42, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, 0x36, 0x0a, 0x15, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, + 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x4a, 0x73, 0x6f, 0x6e, 0x2a, 0x48, 0x0a, + 0x07, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x18, 0x0a, 0x14, 0x4f, 0x52, 0x44, 0x45, + 0x52, 0x5f, 0x42, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, 0x5f, 0x41, + 0x53, 0x43, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, + 0x5f, 0x44, 0x45, 0x53, 0x43, 0x10, 0x02, 0x2a, 0x80, 0x01, 0x0a, 0x0d, 0x42, 0x72, 0x6f, 0x61, + 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x52, 0x4f, + 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x14, 0x42, 0x52, 0x4f, + 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x42, 0x4c, 0x4f, 0x43, + 0x4b, 0x10, 0x01, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x42, 0x52, 0x4f, 0x41, 0x44, + 0x43, 0x41, 0x53, 0x54, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x02, + 0x12, 0x18, 0x0a, 0x14, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x4d, 0x4f, + 0x44, 0x45, 0x5f, 0x41, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x03, 0x32, 0xaa, 0x09, 0x0a, 0x07, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, 0x0a, 0x08, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, + 0x74, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x6d, 0x75, 0x6c, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, + 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x69, 0x6d, 0x75, 0x6c, + 0x61, 0x74, 0x65, 0x12, 0x71, 0x0a, 0x05, 0x47, 0x65, 0x74, 0x54, 0x78, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x54, 0x78, 0x52, 0x03, 0x74, 0x78, 0x73, 0x12, 0x47, 0x0a, 0x0c, 0x74, 0x78, 0x5f, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, - 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, - 0x69, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0b, 0x74, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x73, 0x12, 0x4b, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x65, 0x0a, 0x12, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, - 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x78, - 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x5c, 0x0a, 0x13, 0x42, - 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x74, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x74, - 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x0a, 0x0f, 0x53, 0x69, 0x6d, - 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x02, - 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x42, - 0x02, 0x18, 0x01, 0x52, 0x02, 0x74, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x61, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x67, 0x61, - 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0x22, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, - 0x61, 0x73, 0x68, 0x22, 0x7d, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x02, 0x74, 0x78, 0x12, 0x45, 0x0a, 0x0b, 0x74, - 0x78, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x61, - 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x74, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x78, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x69, - 0x74, 0x68, 0x54, 0x78, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf0, 0x01, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x54, 0x78, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x03, 0x74, 0x78, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, - 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x03, 0x74, 0x78, - 0x73, 0x12, 0x34, 0x0a, 0x08, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x74, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x52, 0x07, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, - 0x69, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x2c, 0x0a, 0x0f, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x39, 0x0a, - 0x10, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x25, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x54, 0x78, 0x52, 0x02, 0x74, 0x78, 0x22, 0x38, 0x0a, 0x0f, 0x54, 0x78, 0x45, 0x6e, - 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x02, 0x74, - 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x52, 0x02, - 0x74, 0x78, 0x22, 0x2d, 0x0a, 0x10, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x22, 0x35, 0x0a, 0x14, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, - 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6d, 0x69, - 0x6e, 0x6f, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, - 0x6d, 0x69, 0x6e, 0x6f, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x15, 0x54, 0x78, 0x45, 0x6e, - 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x42, 0x69, - 0x6e, 0x61, 0x72, 0x79, 0x22, 0x39, 0x0a, 0x14, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, - 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, - 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, - 0x36, 0x0a, 0x15, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6d, 0x69, 0x6e, - 0x6f, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6d, - 0x69, 0x6e, 0x6f, 0x4a, 0x73, 0x6f, 0x6e, 0x2a, 0x48, 0x0a, 0x07, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x42, 0x79, 0x12, 0x18, 0x0a, 0x14, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, - 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, 0x5f, 0x41, 0x53, 0x43, 0x10, 0x01, 0x12, 0x11, - 0x0a, 0x0d, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x43, 0x10, - 0x02, 0x2a, 0x80, 0x01, 0x0a, 0x0d, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, - 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x14, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, - 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x01, 0x1a, 0x02, 0x08, - 0x01, 0x12, 0x17, 0x0a, 0x13, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x4d, - 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x52, - 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x53, 0x59, - 0x4e, 0x43, 0x10, 0x03, 0x32, 0xaa, 0x09, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x7b, 0x0a, 0x08, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x63, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, 0x73, 0x2f, + 0x7b, 0x68, 0x61, 0x73, 0x68, 0x7d, 0x12, 0x7f, 0x0a, 0x0b, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, + 0x61, 0x73, 0x74, 0x54, 0x78, 0x12, 0x25, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, + 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, + 0x61, 0x73, 0x74, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, - 0x22, 0x1b, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x71, 0x0a, - 0x05, 0x47, 0x65, 0x74, 0x54, 0x78, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, + 0x16, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, 0x73, 0x12, 0x7c, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x78, + 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, - 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1f, 0x12, 0x1d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, 0x73, 0x2f, 0x7b, 0x68, 0x61, 0x73, 0x68, 0x7d, - 0x12, 0x7f, 0x0a, 0x0b, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x78, 0x12, - 0x25, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x54, 0x78, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, - 0x63, 0x61, 0x73, 0x74, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, - 0x73, 0x12, 0x7c, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x78, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x25, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, - 0x78, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, 0x73, 0x12, - 0x97, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x69, 0x74, 0x68, - 0x54, 0x78, 0x73, 0x12, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x57, 0x69, 0x74, 0x68, 0x54, 0x78, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x54, - 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x27, 0x12, 0x25, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2f, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x7d, 0x12, 0x79, 0x0a, 0x08, 0x54, 0x78, 0x44, - 0x65, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, - 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, - 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, - 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, - 0x63, 0x6f, 0x64, 0x65, 0x12, 0x79, 0x0a, 0x08, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, - 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, - 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x12, - 0x8e, 0x01, 0x0a, 0x0d, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, - 0x6f, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, - 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, - 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, - 0x1f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, - 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, - 0x6e, 0x6f, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, - 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, + 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2f, 0x74, 0x78, 0x73, 0x12, 0x97, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x54, 0x78, 0x73, 0x12, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x54, 0x78, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x57, 0x69, 0x74, 0x68, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, 0x73, + 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x7d, 0x12, + 0x79, 0x0a, 0x08, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, - 0x22, 0x1f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x6d, 0x69, 0x6e, - 0x6f, 0x42, 0xb9, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, - 0x74, 0x78, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x54, 0x58, 0xaa, - 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x54, 0x78, 0x2e, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xca, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, - 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x3a, 0x3a, 0x54, 0x78, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, + 0x19, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x79, 0x0a, 0x08, 0x54, 0x78, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x45, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, + 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, + 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, + 0x6e, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, + 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, + 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x54, 0x78, 0x44, 0x65, 0x63, + 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x44, + 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x78, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x6d, + 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, + 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x63, 0x6f, 0x64, + 0x65, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x42, 0xb9, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x2c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x74, 0x78, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, + 0x02, 0x03, 0x43, 0x54, 0x58, 0xaa, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x54, + 0x78, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1d, + 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, + 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x78, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/cosmos/tx/v1beta1/service.proto b/proto/cosmos/tx/v1beta1/service.proto index 16b3de0ddafc..798d1ad77150 100644 --- a/proto/cosmos/tx/v1beta1/service.proto +++ b/proto/cosmos/tx/v1beta1/service.proto @@ -37,7 +37,8 @@ service Service { // GetBlockWithTxs fetches a block with decoded txs. // // Since: cosmos-sdk 0.45.2 - rpc GetBlockWithTxs(GetBlockWithTxsRequest) returns (GetBlockWithTxsResponse) { + rpc GetBlockWithTxs(GetBlockWithTxsRequest) + returns (GetBlockWithTxsResponse) { option (google.api.http).get = "/cosmos/tx/v1beta1/txs/block/{height}"; } // TxDecode decodes the transaction. @@ -82,22 +83,35 @@ service Service { // RPC method. message GetTxsEventRequest { // events is the list of transaction event type. - repeated string events = 1; + // Deprecated post v0.47.x: use query instead, which should contain a valid + // events query. + repeated string events = 1 [deprecated = true]; + // pagination defines a pagination for the request. // Deprecated post v0.46.x: use page and limit instead. cosmos.base.query.v1beta1.PageRequest pagination = 2 [deprecated = true]; OrderBy order_by = 3; - // page is the page number to query, starts at 1. If not provided, will default to first page. + + // page is the page number to query, starts at 1. If not provided, will + // default to first page. uint64 page = 4; + // limit is the total number of results to be returned in the result page. // If left empty it will default to a value to be set by each app. uint64 limit = 5; + + // query defines the transaction event query that is proxied to Tendermint's + // TxSearch RPC method. The query must be valid. + // + // Since Cosmos SDK 0.48 + string query = 6; } // OrderBy defines the sorting order enum OrderBy { - // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. + // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults + // to ASC in this case. ORDER_BY_UNSPECIFIED = 0; // ORDER_BY_ASC defines ascending order ORDER_BY_ASC = 1; @@ -127,18 +141,19 @@ message BroadcastTxRequest { BroadcastMode mode = 2; } -// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. +// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC +// method. enum BroadcastMode { // zero-value for mode ordering BROADCAST_MODE_UNSPECIFIED = 0; // DEPRECATED: use BROADCAST_MODE_SYNC instead, // BROADCAST_MODE_BLOCK is not supported by the SDK from v0.47.x onwards. BROADCAST_MODE_BLOCK = 1 [deprecated = true]; - // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for - // a CheckTx execution response only. + // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits + // for a CheckTx execution response only. BROADCAST_MODE_SYNC = 2; - // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns - // immediately. + // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client + // returns immediately. BROADCAST_MODE_ASYNC = 3; } @@ -196,7 +211,8 @@ message GetBlockWithTxsRequest { cosmos.base.query.v1beta1.PageRequest pagination = 2; } -// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method. +// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs +// method. // // Since: cosmos-sdk 0.45.2 message GetBlockWithTxsResponse { diff --git a/server/grpc/server_test.go b/server/grpc/server_test.go index e5d79ed69a81..ed6272b34fa1 100644 --- a/server/grpc/server_test.go +++ b/server/grpc/server_test.go @@ -159,7 +159,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_GetTxsEvent() { _, err := txServiceClient.GetTxsEvent( context.Background(), &txtypes.GetTxsEventRequest{ - Events: []string{"message.action='send'"}, + Query: "message.action='send'", }, ) s.Require().NoError(err) diff --git a/tests/e2e/auth/cli_test.go b/tests/e2e/auth/cli_test.go index 44df46f1931f..45688f5f9121 100644 --- a/tests/e2e/auth/cli_test.go +++ b/tests/e2e/auth/cli_test.go @@ -7,9 +7,7 @@ import ( "testing" "cosmossdk.io/simapp" - "github.com/cosmos/cosmos-sdk/testutil/network" - "github.com/stretchr/testify/suite" ) diff --git a/tests/e2e/auth/suite.go b/tests/e2e/auth/suite.go index ddd3f4741564..23e281cefa20 100644 --- a/tests/e2e/auth/suite.go +++ b/tests/e2e/auth/suite.go @@ -708,8 +708,10 @@ func (s *E2ETestSuite) TestCLIQueryTxsCmdByEvents() { { "fee event happy case", []string{ - fmt.Sprintf("--events=tx.fee=%s", - sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf( + "--query=tx.fee='%s'", + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String(), + ), fmt.Sprintf("--%s=json", flags.FlagOutput), }, false, @@ -717,8 +719,10 @@ func (s *E2ETestSuite) TestCLIQueryTxsCmdByEvents() { { "no matching fee event", []string{ - fmt.Sprintf("--events=tx.fee=%s", - sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(0))).String()), + fmt.Sprintf( + "--query=tx.fee='%s'", + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(0))).String(), + ), fmt.Sprintf("--%s=json", flags.FlagOutput), }, true, diff --git a/tests/e2e/tx/service_test.go b/tests/e2e/tx/service_test.go index 533fedbd8075..b72ba033210f 100644 --- a/tests/e2e/tx/service_test.go +++ b/tests/e2e/tx/service_test.go @@ -7,12 +7,12 @@ import ( "strings" "testing" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" errorsmod "cosmossdk.io/errors" "cosmossdk.io/simapp" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" clienttx "github.com/cosmos/cosmos-sdk/client/tx" @@ -136,7 +136,7 @@ func (s *E2ETestSuite) TestQueryBySig() { b64Sig := base64.StdEncoding.EncodeToString(sig.Signature) sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, b64Sig) res, err := s.queryClient.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{ - Events: []string{sigFormatted}, + Query: sigFormatted, OrderBy: 0, Page: 0, Limit: 10, @@ -145,53 +145,6 @@ func (s *E2ETestSuite) TestQueryBySig() { s.Require().Len(res.Txs, 1) s.Require().Len(res.Txs[0].Signatures, 1) s.Require().Equal(res.Txs[0].Signatures[0], sig.Signature) - - // bad format should error - _, err = s.queryClient.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{Events: []string{"tx.foo.bar='baz'"}}) - s.Require().ErrorContains(err, "invalid event;") -} - -func TestEventRegex(t *testing.T) { - t.Parallel() - - testCases := []struct { - name string - event string - match bool - }{ - { - name: "valid: with quotes", - event: "tx.message='something'", - match: true, - }, - { - name: "valid: with underscores", - event: "claim_reward.message_action='something'", - match: true, - }, - { - name: "valid: no quotes", - event: "tx.message=something", - match: true, - }, - { - name: "invalid: too many separators", - event: "tx.message.foo='bar'", - match: false, - }, - { - name: "valid: symbols ok", - event: "tx.signature='foobar/baz123=='", - match: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - match := authtx.EventRegex.Match([]byte(tc.event)) - require.Equal(t, tc.match, match) - }) - } } func (s E2ETestSuite) TestSimulateTx_GRPC() { @@ -294,48 +247,62 @@ func (s E2ETestSuite) TestGetTxEvents_GRPC() { { "nil request", nil, - true, "request cannot be nil", 0, + true, + "request cannot be nil", + 0, }, { "empty request", &tx.GetTxsEventRequest{}, - true, "must declare at least one event to search", 0, + true, + "query cannot be empty", + 0, }, { "request with dummy event", - &tx.GetTxsEventRequest{Events: []string{"foobar"}}, - true, "event foobar should be of the format: {eventType}.{eventAttribute}={value}", 0, + &tx.GetTxsEventRequest{Query: "foobar"}, + true, + "failed to search for txs", + 0, }, { "request with order-by", &tx.GetTxsEventRequest{ - Events: []string{bankMsgSendEventAction}, + Query: bankMsgSendEventAction, OrderBy: tx.OrderBy_ORDER_BY_ASC, }, - false, "", 3, + false, + "", + 3, }, { "without pagination", &tx.GetTxsEventRequest{ - Events: []string{bankMsgSendEventAction}, + Query: bankMsgSendEventAction, }, - false, "", 3, + false, + "", + 3, }, { "with pagination", &tx.GetTxsEventRequest{ - Events: []string{bankMsgSendEventAction}, - Page: 2, - Limit: 2, + Query: bankMsgSendEventAction, + Page: 2, + Limit: 2, }, - false, "", 1, + false, + "", + 1, }, { "with multi events", &tx.GetTxsEventRequest{ - Events: []string{bankMsgSendEventAction, "message.module='bank'"}, + Query: fmt.Sprintf("%s AND message.module='bank'", bankMsgSendEventAction), }, - false, "", 3, + false, + "", + 3, }, } for _, tc := range testCases { @@ -350,6 +317,7 @@ func (s E2ETestSuite) TestGetTxEvents_GRPC() { s.Require().GreaterOrEqual(len(grpcRes.Txs), 1) s.Require().Equal("foobar", grpcRes.Txs[0].Body.Memo) s.Require().Equal(len(grpcRes.Txs), tc.expLen) + // Make sure fields are populated. // ref: https://github.com/cosmos/cosmos-sdk/issues/8680 // ref: https://github.com/cosmos/cosmos-sdk/issues/8681 @@ -373,47 +341,47 @@ func (s E2ETestSuite) TestGetTxEvents_GRPCGateway() { "empty params", fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.APIAddress), true, - "must declare at least one event to search", 0, + "query cannot be empty", 0, }, { "without pagination", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, bankMsgSendEventAction), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s", val.APIAddress, bankMsgSendEventAction), false, "", 3, }, { "with pagination", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&page=%d&limit=%d", val.APIAddress, bankMsgSendEventAction, 2, 2), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&page=%d&limit=%d", val.APIAddress, bankMsgSendEventAction, 2, 2), false, "", 1, }, { "valid request: order by asc", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=ORDER_BY_ASC", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=ORDER_BY_ASC", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), false, "", 3, }, { "valid request: order by desc", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=ORDER_BY_DESC", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=ORDER_BY_DESC", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), false, "", 3, }, { "invalid request: invalid order by", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=invalid_order", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=invalid_order", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), true, "is not a valid tx.OrderBy", 0, }, { "expect pass with multiple-events", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), false, "", 3, }, { "expect pass with escape event", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, "message.action%3D'/cosmos.bank.v1beta1.MsgSend'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s", val.APIAddress, "message.action%3D'/cosmos.bank.v1beta1.MsgSend'"), false, "", 3, }, @@ -427,11 +395,11 @@ func (s E2ETestSuite) TestGetTxEvents_GRPCGateway() { } else { var result tx.GetTxsEventResponse err = val.ClientCtx.Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) + s.Require().NoError(err, "failed to unmarshal JSON: %s", res) s.Require().GreaterOrEqual(len(result.Txs), 1) s.Require().Equal("foobar", result.Txs[0].Body.Memo) s.Require().NotZero(result.TxResponses[0].Height) - s.Require().Equal(len(result.Txs), tc.expLen) + s.Require().Equal(tc.expLen, len(result.Txs)) } }) } diff --git a/tests/go.mod b/tests/go.mod index 514c164f9473..fdbfb42a6b8b 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -198,7 +198,7 @@ replace ( cosmossdk.io/x/nft => ../x/nft cosmossdk.io/x/tx => ../x/tx cosmossdk.io/x/upgrade => ../x/upgrade - // This can be deleted after the CometBFT PR is merged + // TODO: This can be deleted after the CometBFT PR is merged. github.com/cometbft/cometbft => github.com/cometbft/cometbft v0.0.0-20230203130311-387422ac220d ) diff --git a/types/tx/service.pb.go b/types/tx/service.pb.go index 473f5823a7c2..50c70059c831 100644 --- a/types/tx/service.pb.go +++ b/types/tx/service.pb.go @@ -35,7 +35,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type OrderBy int32 const ( - // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. + // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults + // to ASC in this case. OrderBy_ORDER_BY_UNSPECIFIED OrderBy = 0 // ORDER_BY_ASC defines ascending order OrderBy_ORDER_BY_ASC OrderBy = 1 @@ -63,7 +64,8 @@ func (OrderBy) EnumDescriptor() ([]byte, []int) { return fileDescriptor_e0b00a618705eca7, []int{0} } -// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. +// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC +// method. type BroadcastMode int32 const ( @@ -72,11 +74,11 @@ const ( // DEPRECATED: use BROADCAST_MODE_SYNC instead, // BROADCAST_MODE_BLOCK is not supported by the SDK from v0.47.x onwards. BroadcastMode_BROADCAST_MODE_BLOCK BroadcastMode = 1 // Deprecated: Do not use. - // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for - // a CheckTx execution response only. + // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits + // for a CheckTx execution response only. BroadcastMode_BROADCAST_MODE_SYNC BroadcastMode = 2 - // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns - // immediately. + // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client + // returns immediately. BroadcastMode_BROADCAST_MODE_ASYNC BroadcastMode = 3 ) @@ -106,16 +108,22 @@ func (BroadcastMode) EnumDescriptor() ([]byte, []int) { // RPC method. type GetTxsEventRequest struct { // events is the list of transaction event type. + // Deprecated post v0.47.x: use query instead, which should contain a valid + // events query. Events []string `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` // pagination defines a pagination for the request. // Deprecated post v0.46.x: use page and limit instead. Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` // Deprecated: Do not use. OrderBy OrderBy `protobuf:"varint,3,opt,name=order_by,json=orderBy,proto3,enum=cosmos.tx.v1beta1.OrderBy" json:"order_by,omitempty"` - // page is the page number to query, starts at 1. If not provided, will default to first page. + // page is the page number to query, starts at 1. If not provided, will + // default to first page. Page uint64 `protobuf:"varint,4,opt,name=page,proto3" json:"page,omitempty"` // limit is the total number of results to be returned in the result page. // If left empty it will default to a value to be set by each app. Limit uint64 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"` + // query defines the transaction event query that is proxied to Tendermint's + // TxSearch RPC method. The query must be valid. + Query string `protobuf:"bytes,6,opt,name=query,proto3" json:"query,omitempty"` } func (m *GetTxsEventRequest) Reset() { *m = GetTxsEventRequest{} } @@ -187,6 +195,13 @@ func (m *GetTxsEventRequest) GetLimit() uint64 { return 0 } +func (m *GetTxsEventRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + // GetTxsEventResponse is the response type for the Service.TxsByEvents // RPC method. type GetTxsEventResponse struct { @@ -641,7 +656,8 @@ func (m *GetBlockWithTxsRequest) GetPagination() *query.PageRequest { return nil } -// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method. +// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs +// method. // // Since: cosmos-sdk 0.45.2 type GetBlockWithTxsResponse struct { @@ -1128,84 +1144,85 @@ func init() { func init() { proto.RegisterFile("cosmos/tx/v1beta1/service.proto", fileDescriptor_e0b00a618705eca7) } var fileDescriptor_e0b00a618705eca7 = []byte{ - // 1223 bytes of a gzipped FileDescriptorProto + // 1234 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4d, 0x4f, 0x1b, 0x47, 0x18, 0x66, 0x6d, 0x83, 0xcd, 0x6b, 0x08, 0xce, 0x40, 0xc0, 0x38, 0xc4, 0x98, 0x0d, 0x1f, 0x8e, 0x55, 0xbc, 0x0a, 0x4d, 0xaa, 0x24, 0xaa, 0x54, 0xe1, 0x8f, 0x50, 0x92, 0x26, 0x44, 0x6b, 0xaa, 0x28, 0x55, 0x25, 0x6b, 0x6d, 0x4f, 0xec, 0x6d, 0xec, 0x5d, 0xe3, 0x19, 0xd0, 0x5a, 0x14, 0xb5, - 0xea, 0xb1, 0x87, 0xaa, 0x52, 0x0f, 0xfd, 0x0f, 0xfd, 0x25, 0x3d, 0x46, 0xea, 0xa5, 0xbd, 0x55, - 0xd0, 0x53, 0x4f, 0xfd, 0x09, 0xd5, 0xce, 0x8c, 0xed, 0x5d, 0x7b, 0x17, 0x43, 0x2e, 0x30, 0xb3, - 0xf3, 0xbc, 0xef, 0xf3, 0xcc, 0x3b, 0x33, 0xcf, 0x8c, 0x61, 0xb5, 0x6a, 0x92, 0x96, 0x49, 0x14, - 0x6a, 0x29, 0x27, 0xf7, 0x2b, 0x98, 0x6a, 0xf7, 0x15, 0x82, 0x3b, 0x27, 0x7a, 0x15, 0x67, 0xdb, - 0x1d, 0x93, 0x9a, 0xe8, 0x26, 0x07, 0x64, 0xa9, 0x95, 0x15, 0x80, 0xc4, 0x4a, 0xdd, 0x34, 0xeb, - 0x4d, 0xac, 0x68, 0x6d, 0x5d, 0xd1, 0x0c, 0xc3, 0xa4, 0x1a, 0xd5, 0x4d, 0x83, 0xf0, 0x80, 0xc4, - 0x5d, 0x91, 0xb1, 0xa2, 0x11, 0xac, 0x68, 0x95, 0xaa, 0xde, 0x4f, 0x6c, 0x77, 0x04, 0x28, 0x31, - 0x4a, 0x4b, 0x2d, 0x31, 0x96, 0x71, 0x26, 0x38, 0x3a, 0xc6, 0x9d, 0x6e, 0x1f, 0xd3, 0xd6, 0xea, - 0xba, 0xc1, 0xd8, 0x04, 0x76, 0x85, 0x62, 0xa3, 0x86, 0x3b, 0x2d, 0xdd, 0xa0, 0x0a, 0xed, 0xb6, - 0x31, 0x51, 0x2a, 0x4d, 0xb3, 0xfa, 0xce, 0x77, 0x94, 0xfd, 0xe5, 0xa3, 0xf2, 0x5f, 0x12, 0xa0, - 0x3d, 0x4c, 0x0f, 0x2d, 0x52, 0x3c, 0xc1, 0x06, 0x55, 0xf1, 0xd1, 0x31, 0x26, 0x14, 0x2d, 0xc2, - 0x14, 0xb6, 0xfb, 0x24, 0x2e, 0xa5, 0x82, 0xe9, 0x69, 0x55, 0xf4, 0xd0, 0x33, 0x80, 0x01, 0x7d, - 0x3c, 0x90, 0x92, 0xd2, 0xd1, 0x9d, 0xcd, 0xac, 0xa8, 0x8e, 0xad, 0x35, 0xcb, 0xb4, 0xf6, 0xaa, - 0x94, 0x7d, 0xa5, 0xd5, 0xb1, 0xc8, 0x99, 0x0b, 0xc4, 0x25, 0xd5, 0x11, 0x8d, 0x1e, 0x42, 0xc4, - 0xec, 0xd4, 0x70, 0xa7, 0x5c, 0xe9, 0xc6, 0x83, 0x29, 0x29, 0x7d, 0x63, 0x27, 0x91, 0x1d, 0xa9, - 0x73, 0xf6, 0xc0, 0x86, 0xe4, 0xba, 0x6a, 0xd8, 0xe4, 0x0d, 0x84, 0x20, 0xd4, 0xd6, 0xea, 0x38, - 0x1e, 0x4a, 0x49, 0xe9, 0x90, 0xca, 0xda, 0x68, 0x01, 0x26, 0x9b, 0x7a, 0x4b, 0xa7, 0xf1, 0x49, - 0xf6, 0x91, 0x77, 0xe4, 0x7f, 0x25, 0x98, 0x77, 0xcd, 0x8d, 0xb4, 0x4d, 0x83, 0x60, 0xb4, 0x05, - 0x41, 0x6a, 0xf1, 0x99, 0x45, 0x77, 0x6e, 0x79, 0x70, 0x1e, 0x5a, 0xaa, 0x8d, 0x40, 0x7b, 0x30, - 0x43, 0xad, 0x72, 0x47, 0xc4, 0x91, 0x78, 0x80, 0x45, 0xac, 0xbb, 0xe6, 0xcb, 0xd6, 0xd3, 0x11, - 0x28, 0xc0, 0x6a, 0x94, 0xf6, 0xdb, 0x04, 0x3d, 0x77, 0x95, 0x2d, 0xc8, 0xca, 0xb6, 0x35, 0xb6, - 0x6c, 0x3c, 0x7a, 0xa4, 0x6e, 0x0b, 0x30, 0x49, 0x4d, 0xaa, 0x35, 0x45, 0x05, 0x78, 0x47, 0xc6, - 0x80, 0x72, 0x1d, 0x53, 0xab, 0x55, 0x35, 0x42, 0x6d, 0x19, 0x7c, 0x1d, 0x97, 0x21, 0x42, 0xad, - 0x72, 0xa5, 0x4b, 0xb1, 0x3d, 0x5f, 0x29, 0x3d, 0xa3, 0x86, 0xa9, 0x95, 0xb3, 0xbb, 0xe8, 0x01, - 0x84, 0x5a, 0x66, 0x0d, 0xb3, 0x45, 0xbc, 0xb1, 0x93, 0xf2, 0x28, 0x43, 0x3f, 0xdf, 0x0b, 0xb3, - 0x86, 0x55, 0x86, 0x96, 0xbf, 0x86, 0x79, 0x17, 0x8d, 0x28, 0x69, 0x11, 0xa2, 0x8e, 0x4a, 0x31, - 0xaa, 0xab, 0x16, 0x0a, 0x06, 0x85, 0x92, 0x5f, 0xc3, 0x5c, 0x49, 0x6f, 0x1d, 0x37, 0x35, 0xda, - 0xdb, 0x35, 0xe8, 0x1e, 0x04, 0xa8, 0x25, 0x12, 0x7a, 0xaf, 0x15, 0x2b, 0x50, 0x80, 0x5a, 0xae, - 0xc9, 0x06, 0x5c, 0x93, 0x95, 0x7f, 0x94, 0x20, 0x36, 0xc8, 0x2c, 0x44, 0x7f, 0x0a, 0x91, 0xba, - 0x46, 0xca, 0xba, 0xf1, 0xd6, 0x14, 0x04, 0x6b, 0xfe, 0x8a, 0xf7, 0x34, 0xb2, 0x6f, 0xbc, 0x35, - 0xd5, 0x70, 0x9d, 0x37, 0xd0, 0x23, 0x98, 0xea, 0x60, 0x72, 0xdc, 0xa4, 0xe2, 0x18, 0xa4, 0xfc, - 0x63, 0x55, 0x86, 0x53, 0x05, 0x5e, 0x96, 0x61, 0x86, 0x6d, 0xcb, 0xde, 0x14, 0x11, 0x84, 0x1a, - 0x1a, 0x69, 0x30, 0x0d, 0xd3, 0x2a, 0x6b, 0xcb, 0x67, 0x30, 0x2b, 0x30, 0x42, 0xec, 0xc6, 0xd8, - 0x3a, 0xb0, 0x1a, 0x0c, 0x2d, 0x44, 0xe0, 0x03, 0x17, 0xc2, 0x82, 0xc5, 0x3d, 0x4c, 0x73, 0xb6, - 0x8d, 0xbc, 0xd6, 0x69, 0xe3, 0xd0, 0x22, 0x0e, 0x67, 0x68, 0x60, 0xbd, 0xde, 0xa0, 0x4c, 0x4b, - 0x50, 0x15, 0x3d, 0xf4, 0xf4, 0xc3, 0x9d, 0xc1, 0xb9, 0xbb, 0xe5, 0xff, 0x24, 0x58, 0x1a, 0xa1, - 0xbe, 0xee, 0xc1, 0x7d, 0x00, 0x11, 0x66, 0x81, 0x65, 0xbd, 0x26, 0xa4, 0x2c, 0x67, 0x07, 0x36, - 0x98, 0xe5, 0x06, 0xc8, 0x28, 0xf6, 0x0b, 0x6a, 0x98, 0x41, 0xf7, 0x6b, 0x68, 0x1b, 0x26, 0x59, - 0x53, 0x1c, 0xd0, 0x25, 0x9f, 0x10, 0x95, 0xa3, 0xd0, 0x9e, 0x6b, 0xc6, 0xa1, 0x6b, 0x1d, 0x6a, - 0xd7, 0x94, 0x3f, 0x82, 0xb9, 0x43, 0xab, 0x80, 0xab, 0xf6, 0x29, 0x1b, 0x7b, 0x6e, 0xe5, 0xc7, - 0x10, 0x1b, 0xa0, 0xaf, 0xb5, 0x39, 0xe4, 0x47, 0x36, 0x51, 0xd1, 0x70, 0x12, 0x5d, 0x31, 0x72, - 0xdb, 0x26, 0xed, 0x45, 0x0a, 0xd2, 0x4b, 0x34, 0x3e, 0x84, 0x85, 0x1e, 0x7c, 0xb7, 0xa5, 0x1b, - 0x66, 0x8f, 0xed, 0x0e, 0x80, 0x66, 0xf7, 0xcb, 0xdf, 0x10, 0xd3, 0x10, 0xfb, 0x7d, 0x9a, 0x7d, - 0x79, 0x46, 0x4c, 0x43, 0x7e, 0x02, 0xb7, 0x86, 0xc2, 0x04, 0xd5, 0x1a, 0xcc, 0xf0, 0xb8, 0x8a, - 0x6e, 0x68, 0x9d, 0xae, 0xa0, 0x8b, 0xb2, 0x6f, 0x39, 0xf6, 0x49, 0x7e, 0x6c, 0x53, 0xf2, 0xb2, - 0xb8, 0x28, 0xaf, 0x10, 0xfa, 0x89, 0x4d, 0xeb, 0x0a, 0x15, 0xb4, 0x97, 0xcb, 0xcd, 0x7c, 0x0e, - 0x61, 0x71, 0x3b, 0xa1, 0x38, 0x2c, 0x1c, 0xa8, 0x85, 0xa2, 0x5a, 0xce, 0xbd, 0x29, 0x7f, 0xf9, - 0xb2, 0xf4, 0xaa, 0x98, 0xdf, 0x7f, 0xba, 0x5f, 0x2c, 0xc4, 0x26, 0x50, 0x0c, 0x66, 0xfa, 0x23, - 0xbb, 0xa5, 0x7c, 0x4c, 0x42, 0x37, 0x61, 0xb6, 0xff, 0xa5, 0x50, 0x2c, 0xe5, 0x63, 0x81, 0xcc, - 0xf7, 0x12, 0xcc, 0xba, 0xdc, 0x16, 0x25, 0x21, 0x91, 0x53, 0x0f, 0x76, 0x0b, 0xf9, 0xdd, 0xd2, - 0x61, 0xf9, 0xc5, 0x41, 0xa1, 0x38, 0x94, 0x76, 0x05, 0x16, 0x86, 0xc6, 0x73, 0x5f, 0x1c, 0xe4, - 0x9f, 0xc7, 0xa4, 0x44, 0x20, 0x22, 0xa1, 0x25, 0x98, 0x1f, 0x1a, 0x2d, 0xbd, 0x79, 0x99, 0x8f, - 0x05, 0x6c, 0x9d, 0x43, 0x03, 0xbb, 0x6c, 0x24, 0xb8, 0xf3, 0xdb, 0x34, 0x84, 0x4b, 0xfc, 0xd1, - 0x83, 0x4e, 0x21, 0xd2, 0x33, 0x4b, 0x24, 0x7b, 0x6c, 0x8a, 0x21, 0x8f, 0x4e, 0xdc, 0xbd, 0x14, - 0x23, 0x2c, 0x65, 0xf3, 0x87, 0x3f, 0xfe, 0xf9, 0x25, 0x90, 0x7a, 0x22, 0x65, 0xe4, 0xdb, 0x8a, - 0xc7, 0x83, 0xab, 0x47, 0x78, 0x04, 0x93, 0xcc, 0xf9, 0xd0, 0xaa, 0x47, 0x56, 0xa7, 0x6f, 0x26, - 0x52, 0xfe, 0x00, 0xc1, 0xb9, 0xc1, 0x38, 0x57, 0xd1, 0x1d, 0xc5, 0xeb, 0xa9, 0x45, 0x94, 0x53, - 0xdb, 0x6b, 0xcf, 0xd0, 0x77, 0x10, 0x75, 0x5c, 0x6a, 0x68, 0xe3, 0xb2, 0xbb, 0x70, 0x40, 0xbf, - 0x39, 0x0e, 0x26, 0x44, 0xac, 0x31, 0x11, 0xb7, 0xed, 0x89, 0x2f, 0x7a, 0xeb, 0x40, 0xdf, 0x42, - 0xd4, 0xf1, 0x50, 0xf1, 0x14, 0x30, 0xfa, 0x48, 0xf3, 0x14, 0xe0, 0xf1, 0xde, 0x91, 0x93, 0x4c, - 0x40, 0x1c, 0xf9, 0xb1, 0xff, 0x2a, 0xc1, 0xdc, 0x90, 0xe5, 0xa2, 0x7b, 0xde, 0xb9, 0x3d, 0x6e, - 0x84, 0x44, 0xe6, 0x2a, 0x50, 0x21, 0x65, 0x9b, 0x49, 0xd9, 0x42, 0x1b, 0x3e, 0x0b, 0xc2, 0x9c, - 0x55, 0x39, 0xe5, 0x77, 0xca, 0x19, 0xea, 0x42, 0xa4, 0x77, 0x32, 0x3d, 0x37, 0xe2, 0x90, 0x6d, - 0x7a, 0x6e, 0xc4, 0x61, 0xb3, 0x94, 0xd7, 0x99, 0x86, 0xa4, 0xbd, 0x1e, 0xcb, 0x1e, 0x32, 0x6a, - 0x9c, 0x8e, 0x51, 0x73, 0x2f, 0xf2, 0xa1, 0x76, 0x19, 0xa9, 0x0f, 0xb5, 0xdb, 0x32, 0xc7, 0x51, - 0x63, 0x4e, 0xf7, 0x93, 0x04, 0xb3, 0x2e, 0x1f, 0x44, 0x5b, 0x97, 0x24, 0x77, 0xba, 0x5d, 0x22, - 0x3d, 0x1e, 0x28, 0xa4, 0x64, 0x98, 0x94, 0x75, 0x5b, 0xca, 0xaa, 0xaf, 0x14, 0x85, 0x99, 0x9d, - 0x10, 0xe4, 0x70, 0x48, 0x1f, 0x41, 0xa3, 0xf6, 0xeb, 0x23, 0xc8, 0xc3, 0x6c, 0xc7, 0x09, 0xe2, - 0xcb, 0xc2, 0x05, 0xe5, 0x3e, 0xfb, 0xfd, 0x3c, 0x29, 0xbd, 0x3f, 0x4f, 0x4a, 0x7f, 0x9f, 0x27, - 0xa5, 0x9f, 0x2f, 0x92, 0x13, 0xef, 0x2f, 0x92, 0x13, 0x7f, 0x5e, 0x24, 0x27, 0xbe, 0xda, 0xa8, - 0xeb, 0xb4, 0x71, 0x5c, 0xc9, 0x56, 0xcd, 0x56, 0x2f, 0x09, 0xff, 0xb7, 0x4d, 0x6a, 0xef, 0x7a, - 0xbf, 0x7f, 0xac, 0xca, 0x14, 0xfb, 0xf5, 0xf3, 0xf1, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xfe, - 0xb7, 0x29, 0x3a, 0xfa, 0x0d, 0x00, 0x00, + 0xea, 0xb1, 0x87, 0xaa, 0x52, 0x0f, 0xfd, 0x0f, 0xfd, 0x25, 0x3d, 0x46, 0xea, 0xa5, 0xc7, 0x0a, + 0x7a, 0xea, 0xa5, 0xfd, 0x09, 0xd5, 0xce, 0x8c, 0xed, 0x5d, 0x7b, 0x17, 0x43, 0x2e, 0x30, 0x1f, + 0xcf, 0xfb, 0x3e, 0xcf, 0xbc, 0x33, 0xf3, 0xec, 0x18, 0x56, 0xab, 0x26, 0x69, 0x99, 0x44, 0xa1, + 0x96, 0x72, 0x72, 0xbf, 0x82, 0xa9, 0x76, 0x5f, 0x21, 0xb8, 0x73, 0xa2, 0x57, 0x71, 0xb6, 0xdd, + 0x31, 0xa9, 0x89, 0x6e, 0x72, 0x40, 0x96, 0x5a, 0x59, 0x01, 0x48, 0xac, 0xd4, 0x4d, 0xb3, 0xde, + 0xc4, 0x8a, 0xd6, 0xd6, 0x15, 0xcd, 0x30, 0x4c, 0xaa, 0x51, 0xdd, 0x34, 0x08, 0x0f, 0x48, 0xdc, + 0x15, 0x19, 0x2b, 0x1a, 0xc1, 0x8a, 0x56, 0xa9, 0xea, 0xfd, 0xc4, 0x76, 0x47, 0x80, 0x12, 0xa3, + 0xb4, 0xd4, 0x12, 0x73, 0x19, 0x67, 0x82, 0xa3, 0x63, 0xdc, 0xe9, 0xf6, 0x31, 0x6d, 0xad, 0xae, + 0x1b, 0x8c, 0x4d, 0x60, 0x57, 0x28, 0x36, 0x6a, 0xb8, 0xd3, 0xd2, 0x0d, 0xaa, 0xd0, 0x6e, 0x1b, + 0x13, 0xa5, 0xd2, 0x34, 0xab, 0xef, 0x7c, 0x67, 0xd9, 0x5f, 0x3e, 0x2b, 0xff, 0x2b, 0x01, 0xda, + 0xc3, 0xf4, 0xd0, 0x22, 0xc5, 0x13, 0x6c, 0x50, 0x15, 0x1f, 0x1d, 0x63, 0x42, 0xd1, 0x22, 0x4c, + 0x61, 0xbb, 0x4f, 0xe2, 0x52, 0x2a, 0x98, 0x9e, 0x56, 0x45, 0x0f, 0x3d, 0x03, 0x18, 0xd0, 0xc7, + 0x03, 0x29, 0x29, 0x1d, 0xdd, 0xd9, 0xcc, 0x8a, 0xea, 0xd8, 0x5a, 0xb3, 0x4c, 0x6b, 0xaf, 0x4a, + 0xd9, 0x57, 0x5a, 0x1d, 0x8b, 0x9c, 0xb9, 0x40, 0x5c, 0x52, 0x1d, 0xd1, 0xe8, 0x21, 0x44, 0xcc, + 0x4e, 0x0d, 0x77, 0xca, 0x95, 0x6e, 0x3c, 0x98, 0x92, 0xd2, 0x37, 0x76, 0x12, 0xd9, 0x91, 0x3a, + 0x67, 0x0f, 0x6c, 0x48, 0xae, 0xab, 0x86, 0x4d, 0xde, 0x40, 0x08, 0x42, 0x6d, 0xad, 0x8e, 0xe3, + 0xa1, 0x94, 0x94, 0x0e, 0xa9, 0xac, 0x8d, 0x16, 0x60, 0xb2, 0xa9, 0xb7, 0x74, 0x1a, 0x9f, 0x64, + 0x83, 0xbc, 0x63, 0x8f, 0x32, 0x35, 0xf1, 0xa9, 0x94, 0x94, 0x9e, 0x56, 0x79, 0x47, 0xfe, 0x47, + 0x82, 0x79, 0xd7, 0x8a, 0x49, 0xdb, 0x34, 0x08, 0x46, 0x5b, 0x10, 0xa4, 0x16, 0x5f, 0x6f, 0x74, + 0xe7, 0x96, 0x87, 0x92, 0x43, 0x4b, 0xb5, 0x11, 0x68, 0x0f, 0x66, 0xa8, 0x55, 0xee, 0x88, 0x38, + 0x12, 0x0f, 0xb0, 0x88, 0x75, 0x57, 0x15, 0xd8, 0x2e, 0x3b, 0x02, 0x05, 0x58, 0x8d, 0xd2, 0x7e, + 0x9b, 0xa0, 0xe7, 0xae, 0x62, 0x06, 0x59, 0x31, 0xb7, 0xc6, 0x16, 0x93, 0x47, 0x8f, 0x54, 0x73, + 0x01, 0x26, 0xa9, 0x49, 0xb5, 0xa6, 0xa8, 0x0b, 0xef, 0xc8, 0x18, 0x50, 0xae, 0x63, 0x6a, 0xb5, + 0xaa, 0x46, 0xa8, 0x2d, 0x83, 0xef, 0xee, 0x32, 0x44, 0xa8, 0x55, 0xae, 0x74, 0x29, 0xb6, 0xd7, + 0x2b, 0xa5, 0x67, 0xd4, 0x30, 0xb5, 0x72, 0x76, 0x17, 0x3d, 0x80, 0x50, 0xcb, 0xac, 0x61, 0xb6, + 0xb5, 0x37, 0x76, 0x52, 0x1e, 0x65, 0xe8, 0xe7, 0x7b, 0x61, 0xd6, 0xb0, 0xca, 0xd0, 0xf2, 0xd7, + 0x30, 0xef, 0xa2, 0x11, 0x25, 0x2d, 0x42, 0xd4, 0x51, 0x29, 0x46, 0x75, 0xd5, 0x42, 0xc1, 0xa0, + 0x50, 0xf2, 0x6b, 0x98, 0x2b, 0xe9, 0xad, 0xe3, 0xa6, 0x46, 0x7b, 0x67, 0x09, 0xdd, 0x83, 0x00, + 0xb5, 0x44, 0x42, 0xef, 0xbd, 0x62, 0x05, 0x0a, 0x50, 0xcb, 0xb5, 0xd8, 0x80, 0x6b, 0xb1, 0xf2, + 0x8f, 0x12, 0xc4, 0x06, 0x99, 0x85, 0xe8, 0x4f, 0x21, 0x52, 0xd7, 0x48, 0x59, 0x37, 0xde, 0x9a, + 0x82, 0x60, 0xcd, 0x5f, 0xf1, 0x9e, 0x46, 0xf6, 0x8d, 0xb7, 0xa6, 0x1a, 0xae, 0xf3, 0x06, 0x7a, + 0x04, 0x53, 0x1d, 0x4c, 0x8e, 0x9b, 0x54, 0x5c, 0x8e, 0x94, 0x7f, 0xac, 0xca, 0x70, 0xaa, 0xc0, + 0xcb, 0x32, 0xcc, 0xb0, 0x63, 0xd9, 0x5b, 0x22, 0x82, 0x50, 0x43, 0x23, 0x0d, 0xa6, 0x61, 0x5a, + 0x65, 0x6d, 0xf9, 0x0c, 0x66, 0x05, 0x46, 0x88, 0xdd, 0x18, 0x5b, 0x07, 0x56, 0x83, 0xa1, 0x8d, + 0x08, 0x7c, 0xe0, 0x46, 0x58, 0xb0, 0xb8, 0x87, 0x69, 0xce, 0x36, 0x97, 0xd7, 0x3a, 0x6d, 0x1c, + 0x5a, 0xc4, 0xe1, 0x17, 0x0d, 0xac, 0xd7, 0x1b, 0x94, 0x69, 0x09, 0xaa, 0xa2, 0x87, 0x9e, 0x7e, + 0xb8, 0x5f, 0x38, 0x4f, 0xb7, 0xfc, 0x9f, 0x04, 0x4b, 0x23, 0xd4, 0xd7, 0xbd, 0xb8, 0x0f, 0x20, + 0xc2, 0x8c, 0xb1, 0xac, 0xd7, 0x84, 0x94, 0xe5, 0xec, 0xc0, 0x1c, 0xb3, 0xdc, 0x16, 0x19, 0xc5, + 0x7e, 0x41, 0x0d, 0x33, 0xe8, 0x7e, 0x0d, 0x6d, 0xc3, 0x24, 0x6b, 0x8a, 0x0b, 0xba, 0xe4, 0x13, + 0xa2, 0x72, 0x14, 0xda, 0x73, 0xad, 0x38, 0x74, 0xad, 0x4b, 0xed, 0x5a, 0xf2, 0x47, 0x30, 0x77, + 0x68, 0x15, 0x70, 0xd5, 0xbe, 0x65, 0x63, 0xef, 0xad, 0xfc, 0x18, 0x62, 0x03, 0xf4, 0xb5, 0x0e, + 0x87, 0xfc, 0xc8, 0x26, 0x2a, 0x1a, 0x4e, 0xa2, 0x2b, 0x46, 0x6e, 0xdb, 0xa4, 0xbd, 0x48, 0x41, + 0x7a, 0x89, 0xc6, 0x87, 0xb0, 0xd0, 0x83, 0xef, 0xb6, 0x74, 0xc3, 0xec, 0xb1, 0xdd, 0x01, 0xd0, + 0xec, 0x7e, 0xf9, 0x1b, 0x62, 0x1a, 0xe2, 0xbc, 0x4f, 0xb3, 0x91, 0x67, 0xc4, 0x34, 0xe4, 0x27, + 0x70, 0x6b, 0x28, 0x4c, 0x50, 0xad, 0xc1, 0x0c, 0x8f, 0xab, 0xe8, 0x86, 0xd6, 0xe9, 0x0a, 0xba, + 0x28, 0x1b, 0xcb, 0xb1, 0x21, 0xf9, 0xb1, 0x4d, 0xc9, 0xcb, 0xe2, 0xa2, 0xbc, 0x42, 0xe8, 0x27, + 0x36, 0xad, 0x2b, 0x54, 0xd0, 0x5e, 0x2e, 0x37, 0xf3, 0x39, 0x84, 0xc5, 0x37, 0x0b, 0xc5, 0x61, + 0xe1, 0x40, 0x2d, 0x14, 0xd5, 0x72, 0xee, 0x4d, 0xf9, 0xcb, 0x97, 0xa5, 0x57, 0xc5, 0xfc, 0xfe, + 0xd3, 0xfd, 0x62, 0x21, 0x36, 0x81, 0x62, 0x30, 0xd3, 0x9f, 0xd9, 0x2d, 0xe5, 0x63, 0x12, 0xba, + 0x09, 0xb3, 0xfd, 0x91, 0x42, 0xb1, 0x94, 0x8f, 0x05, 0x32, 0xdf, 0x4b, 0x30, 0xeb, 0x72, 0x5b, + 0x94, 0x84, 0x44, 0x4e, 0x3d, 0xd8, 0x2d, 0xe4, 0x77, 0x4b, 0x87, 0xe5, 0x17, 0x07, 0x85, 0xe2, + 0x50, 0xda, 0x15, 0x58, 0x18, 0x9a, 0xcf, 0x7d, 0x71, 0x90, 0x7f, 0x1e, 0x93, 0x12, 0x81, 0x88, + 0x84, 0x96, 0x60, 0x7e, 0x68, 0xb6, 0xf4, 0xe6, 0x65, 0x3e, 0x16, 0xb0, 0x75, 0x0e, 0x4d, 0xec, + 0xb2, 0x99, 0xe0, 0xce, 0x6f, 0xd3, 0x10, 0x2e, 0xf1, 0xa7, 0x10, 0x3a, 0x85, 0x48, 0xcf, 0x2c, + 0x91, 0xec, 0x71, 0x28, 0x86, 0x3c, 0x3a, 0x71, 0xf7, 0x52, 0x8c, 0xb0, 0x94, 0xcd, 0x1f, 0xfe, + 0xf8, 0xfb, 0x97, 0x40, 0xea, 0x89, 0x94, 0x91, 0x6f, 0x2b, 0x1e, 0xcf, 0xb0, 0x1e, 0xe1, 0x11, + 0x4c, 0x32, 0xe7, 0x43, 0xab, 0x1e, 0x59, 0x9d, 0xbe, 0x99, 0x48, 0xf9, 0x03, 0x04, 0xe7, 0x06, + 0xe3, 0x5c, 0x45, 0x77, 0x14, 0xaf, 0x07, 0x18, 0x51, 0x4e, 0x6d, 0xaf, 0x3d, 0x43, 0xdf, 0x41, + 0xd4, 0xf1, 0x51, 0x43, 0x1b, 0x97, 0x7d, 0x0b, 0x07, 0xf4, 0x9b, 0xe3, 0x60, 0x42, 0xc4, 0x1a, + 0x13, 0x71, 0xdb, 0x5e, 0xf8, 0xa2, 0xb7, 0x0e, 0xf4, 0x2d, 0x44, 0x1d, 0x0f, 0x15, 0x4f, 0x01, + 0xa3, 0x4f, 0x37, 0x4f, 0x01, 0x1e, 0xef, 0x1d, 0x39, 0xc9, 0x04, 0xc4, 0x91, 0x1f, 0xfb, 0xaf, + 0x12, 0xcc, 0x0d, 0x59, 0x2e, 0xba, 0xe7, 0x9d, 0xdb, 0xe3, 0x8b, 0x90, 0xc8, 0x5c, 0x05, 0x2a, + 0xa4, 0x6c, 0x33, 0x29, 0x5b, 0x68, 0xc3, 0x67, 0x43, 0x98, 0xb3, 0x2a, 0xa7, 0xfc, 0x9b, 0x72, + 0x86, 0xba, 0x10, 0xe9, 0xdd, 0x4c, 0xcf, 0x83, 0x38, 0x64, 0x9b, 0x9e, 0x07, 0x71, 0xd8, 0x2c, + 0xe5, 0x75, 0xa6, 0x21, 0x69, 0xef, 0xc7, 0xb2, 0x87, 0x8c, 0x1a, 0xa7, 0x63, 0xd4, 0xdc, 0x8b, + 0x7c, 0xa8, 0x5d, 0x46, 0xea, 0x43, 0xed, 0xb6, 0xcc, 0x71, 0xd4, 0x98, 0xd3, 0xfd, 0x24, 0xc1, + 0xac, 0xcb, 0x07, 0xd1, 0xd6, 0x25, 0xc9, 0x9d, 0x6e, 0x97, 0x48, 0x8f, 0x07, 0x0a, 0x29, 0x19, + 0x26, 0x65, 0xdd, 0x96, 0xb2, 0xea, 0x2b, 0x45, 0x61, 0x66, 0x27, 0x04, 0x39, 0x1c, 0xd2, 0x47, + 0xd0, 0xa8, 0xfd, 0xfa, 0x08, 0xf2, 0x30, 0xdb, 0x71, 0x82, 0xf8, 0xb6, 0x70, 0x41, 0xb9, 0xcf, + 0x7e, 0x3f, 0x4f, 0x4a, 0xef, 0xcf, 0x93, 0xd2, 0x5f, 0xe7, 0x49, 0xe9, 0xe7, 0x8b, 0xe4, 0xc4, + 0xfb, 0x8b, 0xe4, 0xc4, 0x9f, 0x17, 0xc9, 0x89, 0xaf, 0x36, 0xea, 0x3a, 0x6d, 0x1c, 0x57, 0xb2, + 0x55, 0xb3, 0xd5, 0x4b, 0xc2, 0xff, 0x6d, 0x93, 0xda, 0xbb, 0xde, 0xaf, 0x22, 0xab, 0x32, 0xc5, + 0x7e, 0x13, 0x7d, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x24, 0x1f, 0x2c, 0x10, 0x0e, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1634,6 +1651,13 @@ func (m *GetTxsEventRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Query) > 0 { + i -= len(m.Query) + copy(dAtA[i:], m.Query) + i = encodeVarintService(dAtA, i, uint64(len(m.Query))) + i-- + dAtA[i] = 0x32 + } if m.Limit != 0 { i = encodeVarintService(dAtA, i, uint64(m.Limit)) i-- @@ -2376,6 +2400,10 @@ func (m *GetTxsEventRequest) Size() (n int) { if m.Limit != 0 { n += 1 + sovService(uint64(m.Limit)) } + l = len(m.Query) + if l > 0 { + n += 1 + l + sovService(uint64(l)) + } return n } @@ -2807,6 +2835,38 @@ func (m *GetTxsEventRequest) Unmarshal(dAtA []byte) error { break } } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowService + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthService + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthService + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipService(dAtA[iNdEx:]) diff --git a/x/auth/client/cli/query.go b/x/auth/client/cli/query.go index a07f710602d5..5995a4c3d37b 100644 --- a/x/auth/client/cli/query.go +++ b/x/auth/client/cli/query.go @@ -6,16 +6,14 @@ import ( "strconv" "strings" - cmttypes "github.com/cometbft/cometbft/types" - "github.com/spf13/cobra" - errorsmod "cosmossdk.io/errors" + "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/query" + querytypes "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/version" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -266,55 +264,29 @@ func QueryTxsByEventsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "txs", Short: "Query for paginated transactions that match a set of events", - Long: strings.TrimSpace( - fmt.Sprintf(` -Search for transactions that match the exact given events where results are paginated. -Each event takes the form of '%s'. Please refer -to each module's documentation for the full set of events to query for. Each module -documents its respective events under 'xx_events.md'. + Long: `Search for transactions that match the exact given events where results are paginated. +The events query is directly passed to Tendermint's RPC TxSearch method and must +conform to Tendermint's query syntax. -Example: -$ %s query txs --%s 'message.sender=cosmos1...&message.action=withdraw_delegator_reward' --page 1 --limit 30 -`, EventFormat, version.AppName, FlagEvents), +Please refer to each module's documentation for the full set of events to query +for. Each module documents its respective events under 'xx_events.md'. +`, + Example: fmt.Sprintf( + "$ %s query txs --query \"message.sender='cosmos1...' AND message.action='withdraw_delegator_reward' AND tx.height > 7\" --page 1 --limit 30", + version.AppName, ), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } - eventsRaw, _ := cmd.Flags().GetString(FlagEvents) - eventsStr := strings.Trim(eventsRaw, "'") - - var events []string - if strings.Contains(eventsStr, "&") { - events = strings.Split(eventsStr, "&") - } else { - events = append(events, eventsStr) - } - - var tmEvents []string - - for _, event := range events { - if !strings.Contains(event, "=") { - return fmt.Errorf("invalid event; event %s should be of the format: %s", event, EventFormat) - } else if strings.Count(event, "=") > 1 { - return fmt.Errorf("invalid event; event %s should be of the format: %s", event, EventFormat) - } - - tokens := strings.Split(event, "=") - if tokens[0] == cmttypes.TxHeightKey { - event = fmt.Sprintf("%s=%s", tokens[0], tokens[1]) - } else { - event = fmt.Sprintf("%s='%s'", tokens[0], tokens[1]) - } - - tmEvents = append(tmEvents, event) - } + query, _ := cmd.Flags().GetString(FlagQuery) page, _ := cmd.Flags().GetInt(flags.FlagPage) limit, _ := cmd.Flags().GetInt(flags.FlagLimit) + orderBy, _ := cmd.Flags().GetString(FlagOrderBy) - txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, page, limit, "") + txs, err := authtx.QueryTxsByEvents(clientCtx, page, limit, query, orderBy) if err != nil { return err } @@ -324,10 +296,11 @@ $ %s query txs --%s 'message.sender=cosmos1...&message.action=withdraw_delegator } flags.AddQueryFlagsToCmd(cmd) - cmd.Flags().Int(flags.FlagPage, query.DefaultPage, "Query a specific page of paginated results") - cmd.Flags().Int(flags.FlagLimit, query.DefaultLimit, "Query number of transactions results per page returned") - cmd.Flags().String(FlagEvents, "", fmt.Sprintf("list of transaction events in the form of %s", EventFormat)) - cmd.MarkFlagRequired(FlagEvents) + cmd.Flags().Int(flags.FlagPage, querytypes.DefaultPage, "Query a specific page of paginated results") + cmd.Flags().Int(flags.FlagLimit, querytypes.DefaultLimit, "Query number of transactions results per page returned") + cmd.Flags().String(FlagQuery, "", "The transactions events query per Tendermint's query semantics") + cmd.Flags().String(FlagOrderBy, "", "The ordering semantics (asc|dsc)") + _ = cmd.MarkFlagRequired(FlagQuery) return cmd } @@ -357,71 +330,74 @@ $ %s query tx --%s=%s , switch typ { case TypeHash: - { - if args[0] == "" { - return fmt.Errorf("argument should be a tx hash") - } - - // If hash is given, then query the tx by hash. - output, err := authtx.QueryTx(clientCtx, args[0]) - if err != nil { - return err - } - - if output.Empty() { - return fmt.Errorf("no transaction found with hash %s", args[0]) - } - - return clientCtx.PrintProto(output) + if args[0] == "" { + return fmt.Errorf("argument should be a tx hash") } + + // if hash is given, then query the tx by hash + output, err := authtx.QueryTx(clientCtx, args[0]) + if err != nil { + return err + } + + if output.Empty() { + return fmt.Errorf("no transaction found with hash %s", args[0]) + } + + return clientCtx.PrintProto(output) + case TypeSig: - { - sigParts, err := ParseSigArgs(args) - if err != nil { - return err - } - tmEvents := make([]string, len(sigParts)) - for i, sig := range sigParts { - tmEvents[i] = fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig) - } - - txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, query.DefaultPage, query.DefaultLimit, "") - if err != nil { - return err - } - if len(txs.Txs) == 0 { - return fmt.Errorf("found no txs matching given signatures") - } - if len(txs.Txs) > 1 { - // This case means there's a bug somewhere else in the code. Should not happen. - return errors.ErrLogic.Wrapf("found %d txs matching given signatures", len(txs.Txs)) - } - - return clientCtx.PrintProto(txs.Txs[0]) + sigParts, err := ParseSigArgs(args) + if err != nil { + return err + } + + events := make([]string, len(sigParts)) + for i, sig := range sigParts { + events[i] = fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig) + } + + query := strings.Join(events, " AND ") + + txs, err := authtx.QueryTxsByEvents(clientCtx, querytypes.DefaultPage, querytypes.DefaultLimit, query, "") + if err != nil { + return err + } + + if len(txs.Txs) == 0 { + return fmt.Errorf("found no txs matching given signatures") } + if len(txs.Txs) > 1 { + // This case means there's a bug somewhere else in the code as this + // should not happen. + return errors.ErrLogic.Wrapf("found %d txs matching given signatures", len(txs.Txs)) + } + + return clientCtx.PrintProto(txs.Txs[0]) + case TypeAccSeq: - { - if args[0] == "" { - return fmt.Errorf("`acc_seq` type takes an argument '/'") - } - - tmEvents := []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeyAccountSequence, args[0]), - } - txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, query.DefaultPage, query.DefaultLimit, "") - if err != nil { - return err - } - if len(txs.Txs) == 0 { - return fmt.Errorf("found no txs matching given address and sequence combination") - } - if len(txs.Txs) > 1 { - // This case means there's a bug somewhere else in the code. Should not happen. - return fmt.Errorf("found %d txs matching given address and sequence combination", len(txs.Txs)) - } - - return clientCtx.PrintProto(txs.Txs[0]) + if args[0] == "" { + return fmt.Errorf("`acc_seq` type takes an argument '/'") } + + query := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeyAccountSequence, args[0]) + + txs, err := authtx.QueryTxsByEvents(clientCtx, querytypes.DefaultPage, querytypes.DefaultLimit, query, "") + if err != nil { + return err + } + + if len(txs.Txs) == 0 { + return fmt.Errorf("found no txs matching given address and sequence combination") + } + if len(txs.Txs) > 1 { + // This case means there's a bug somewhere else in the code as this + // should not happen. + return fmt.Errorf("found %d txs matching given address and sequence combination", len(txs.Txs)) + } + + return clientCtx.PrintProto(txs.Txs[0]) + default: return fmt.Errorf("unknown --%s value %s", FlagType, typ) } diff --git a/x/auth/client/cli/suite_test.go b/x/auth/client/cli/suite_test.go index 1d8a106aacb8..29bb0a2f05f5 100644 --- a/x/auth/client/cli/suite_test.go +++ b/x/auth/client/cli/suite_test.go @@ -292,8 +292,10 @@ func (s *CLITestSuite) TestCLIQueryTxsCmdByEvents() { { "fee event happy case", []string{ - fmt.Sprintf("--events=tx.fee=%s", - sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()), + fmt.Sprintf( + "--query=tx.fee='%s'", + sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String(), + ), fmt.Sprintf("--%s=json", flags.FlagOutput), }, "", @@ -301,8 +303,10 @@ func (s *CLITestSuite) TestCLIQueryTxsCmdByEvents() { { "no matching fee event", []string{ - fmt.Sprintf("--events=tx.fee=%s", - sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(0))).String()), + fmt.Sprintf( + "--query=tx.fee='%s'", + sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(0))).String(), + ), fmt.Sprintf("--%s=json", flags.FlagOutput), }, "", diff --git a/x/auth/tx/query.go b/x/auth/tx/query.go index c052451ead0c..62a1bb7e136f 100644 --- a/x/auth/tx/query.go +++ b/x/auth/tx/query.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "errors" "fmt" - "strings" "time" coretypes "github.com/cometbft/cometbft/rpc/core/types" @@ -13,40 +12,39 @@ import ( "github.com/cosmos/cosmos-sdk/client" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + querytypes "github.com/cosmos/cosmos-sdk/types/query" ) -// QueryTxsByEvents performs a search for transactions for a given set of events -// via the CometBFT RPC. An event takes the form of: -// "{eventAttribute}.{attributeKey} = '{attributeValue}'". Each event is -// concatenated with an 'AND' operand. It returns a slice of Info object -// containing txs and metadata. An error is returned if the query fails. -// If an empty string is provided it will order txs by asc -func QueryTxsByEvents(clientCtx client.Context, events []string, page, limit int, orderBy string) (*sdk.SearchTxsResult, error) { - if len(events) == 0 { - return nil, errors.New("must declare at least one event to search") +// QueryTxsByEvents retrieves a list of paginated transactions from Tendermint's +// TxSearch RPC method given a set of pagination criteria and an events query. +// Note, the events query must be valid based on Tendermint's query semantics. +// An error is returned if the query or parsing fails or if the query is empty. +// +// Note, if an empty orderBy is provided, the default behavior is ascending. If +// negative values are provided for page or limit, defaults will be used. +func QueryTxsByEvents(clientCtx client.Context, page, limit int, query, orderBy string) (*sdk.SearchTxsResult, error) { + if len(query) == 0 { + return nil, errors.New("query cannot be empty") } + // Tendermint node.TxSearch that is used for querying txs defines pages + // starting from 1, so we default to 1 if not provided in the request. if page <= 0 { - return nil, errors.New("page must be greater than 0") + page = 1 } if limit <= 0 { - return nil, errors.New("limit must be greater than 0") + limit = querytypes.DefaultLimit } - // XXX: implement ANY - query := strings.Join(events, " AND ") - node, err := clientCtx.GetNode() if err != nil { return nil, err } - // TODO: this may not always need to be proven - // https://github.com/cosmos/cosmos-sdk/issues/6807 - resTxs, err := node.TxSearch(context.Background(), query, true, &page, &limit, orderBy) + resTxs, err := node.TxSearch(context.Background(), query, false, &page, &limit, orderBy) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to search for txs: %w", err) } resBlocks, err := getBlocksForTxResults(clientCtx, resTxs.Txs) @@ -59,9 +57,7 @@ func QueryTxsByEvents(clientCtx client.Context, events []string, page, limit int return nil, err } - result := sdk.NewSearchTxsResult(uint64(resTxs.TotalCount), uint64(len(txs)), uint64(page), uint64(limit), txs) - - return result, nil + return sdk.NewSearchTxsResult(uint64(resTxs.TotalCount), uint64(len(txs)), uint64(page), uint64(limit), txs), nil } // QueryTx queries for a single transaction by a hash string in hex format. An diff --git a/x/auth/tx/service.go b/x/auth/tx/service.go index bb0e16c8a14f..c4bfb2b66582 100644 --- a/x/auth/tx/service.go +++ b/x/auth/tx/service.go @@ -3,7 +3,6 @@ package tx import ( "context" "fmt" - "regexp" "strings" gogogrpc "github.com/cosmos/gogoproto/grpc" @@ -41,16 +40,7 @@ func NewTxServer(clientCtx client.Context, simulate baseAppSimulateFn, interface } } -var ( - _ txtypes.ServiceServer = txServer{} - - // EventRegex checks that an event string is formatted with {alphabetic}.{alphabetic}={value} - EventRegex = regexp.MustCompile(`^[a-zA-Z_]+\.[a-zA-Z_]+=\S+$`) -) - -const ( - eventFormat = "{eventType}.{eventAttribute}={value}" -) +var _ txtypes.ServiceServer = txServer{} // GetTxsEvent implements the ServiceServer.TxsByEvents RPC method. func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventRequest) (*txtypes.GetTxsEventResponse, error) { @@ -58,37 +48,14 @@ func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventReque return nil, status.Error(codes.InvalidArgument, "request cannot be nil") } - page := int(req.Page) - // CometBFT node.TxSearch that is used for querying txs defines pages starting from 1, - // so we default to 1 if not provided in the request. - if page == 0 { - page = 1 - } - - limit := int(req.Limit) - if limit == 0 { - limit = query.DefaultLimit - } orderBy := parseOrderBy(req.OrderBy) - if len(req.Events) == 0 { - return nil, status.Error(codes.InvalidArgument, "must declare at least one event to search") - } - - for _, event := range req.Events { - if !EventRegex.Match([]byte(event)) { - return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid event; event %s should be of the format: %s", event, eventFormat)) - } - } - - result, err := QueryTxsByEvents(s.clientCtx, req.Events, page, limit, orderBy) + result, err := QueryTxsByEvents(s.clientCtx, int(req.Page), int(req.Limit), req.Query, orderBy) if err != nil { - return nil, err + return nil, status.Error(codes.Internal, err.Error()) } - // Create a proto codec, we need it to unmarshal the tx bytes. txsList := make([]*txtypes.Tx, len(result.Txs)) - for i, tx := range result.Txs { protoTx, ok := tx.Tx.GetCachedValue().(*txtypes.Tx) if !ok { diff --git a/x/gov/client/utils/query.go b/x/gov/client/utils/query.go index 5ced5704ab10..cc386696f610 100644 --- a/x/gov/client/utils/query.go +++ b/x/gov/client/utils/query.go @@ -2,6 +2,7 @@ package utils import ( "fmt" + "strings" "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" @@ -443,13 +444,15 @@ func QueryProposalByID(proposalID uint64, clientCtx client.Context, queryRoute s // In searching for events, we search for both `Type()`s, and we use the // `combineEvents` function here to merge events. func combineEvents(clientCtx client.Context, page int, eventGroups ...[]string) (*sdk.SearchTxsResult, error) { - // Only the Txs field will be populated in the final SearchTxsResult. + // only the Txs field will be populated in the final SearchTxsResult allTxs := []*sdk.TxResponse{} for _, events := range eventGroups { - res, err := authtx.QueryTxsByEvents(clientCtx, events, page, defaultLimit, "") + q := strings.Join(events, " AND ") + res, err := authtx.QueryTxsByEvents(clientCtx, page, defaultLimit, q, "") if err != nil { return nil, err } + allTxs = append(allTxs, res.Txs...) }