diff --git a/CHANGELOG.md b/CHANGELOG.md index 06833ef15560c..9c2ab25bfb4f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features * (cli) [#16887](https://github.com/cosmos/cosmos-sdk/pull/16887) Add two new CLI commands: `tx simulate` for simulating a transaction; `query block-results` for querying CometBFT RPC for block results. +* (x/gov) [#16976](https://github.com/cosmos/cosmos-sdk/pull/16976) Add `failed_reason` field to `Proposal` under `x/gov` to indicate the reason for a failed proposal. Referenced from [#238](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/238) under `bnb-chain/greenfield-cosmos-sdk`. ### Improvements @@ -53,6 +54,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (server) [#16827](https://github.com/cosmos/cosmos-sdk/pull/16827) Properly use `--trace` flag (before it was setting the trace level instead of displaying the stacktraces). * (x/bank) [#16841](https://github.com/cosmos/cosmos-sdk/pull/16841) correctly process legacy `DenomAddressIndex` values. +* (types/query) [#16905](https://github.com/cosmos/cosmos-sdk/pull/16905) – Collections Pagination now applies proper count when filtering results. ### API Breaking Changes diff --git a/api/cosmos/gov/v1/gov.pulsar.go b/api/cosmos/gov/v1/gov.pulsar.go index 0e647598222ff..c5df206274186 100644 --- a/api/cosmos/gov/v1/gov.pulsar.go +++ b/api/cosmos/gov/v1/gov.pulsar.go @@ -1211,6 +1211,7 @@ var ( fd_Proposal_summary protoreflect.FieldDescriptor fd_Proposal_proposer protoreflect.FieldDescriptor fd_Proposal_expedited protoreflect.FieldDescriptor + fd_Proposal_failed_reason protoreflect.FieldDescriptor ) func init() { @@ -1230,6 +1231,7 @@ func init() { fd_Proposal_summary = md_Proposal.Fields().ByName("summary") fd_Proposal_proposer = md_Proposal.Fields().ByName("proposer") fd_Proposal_expedited = md_Proposal.Fields().ByName("expedited") + fd_Proposal_failed_reason = md_Proposal.Fields().ByName("failed_reason") } var _ protoreflect.Message = (*fastReflection_Proposal)(nil) @@ -1381,6 +1383,12 @@ func (x *fastReflection_Proposal) Range(f func(protoreflect.FieldDescriptor, pro return } } + if x.FailedReason != "" { + value := protoreflect.ValueOfString(x.FailedReason) + if !f(fd_Proposal_failed_reason, value) { + return + } + } } // Has reports whether a field is populated. @@ -1424,6 +1432,8 @@ func (x *fastReflection_Proposal) Has(fd protoreflect.FieldDescriptor) bool { return x.Proposer != "" case "cosmos.gov.v1.Proposal.expedited": return x.Expedited != false + case "cosmos.gov.v1.Proposal.failed_reason": + return x.FailedReason != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.gov.v1.Proposal")) @@ -1468,6 +1478,8 @@ func (x *fastReflection_Proposal) Clear(fd protoreflect.FieldDescriptor) { x.Proposer = "" case "cosmos.gov.v1.Proposal.expedited": x.Expedited = false + case "cosmos.gov.v1.Proposal.failed_reason": + x.FailedReason = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.gov.v1.Proposal")) @@ -1532,6 +1544,9 @@ func (x *fastReflection_Proposal) Get(descriptor protoreflect.FieldDescriptor) p case "cosmos.gov.v1.Proposal.expedited": value := x.Expedited return protoreflect.ValueOfBool(value) + case "cosmos.gov.v1.Proposal.failed_reason": + value := x.FailedReason + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.gov.v1.Proposal")) @@ -1584,6 +1599,8 @@ func (x *fastReflection_Proposal) Set(fd protoreflect.FieldDescriptor, value pro x.Proposer = value.Interface().(string) case "cosmos.gov.v1.Proposal.expedited": x.Expedited = value.Bool() + case "cosmos.gov.v1.Proposal.failed_reason": + x.FailedReason = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.gov.v1.Proposal")) @@ -1655,6 +1672,8 @@ func (x *fastReflection_Proposal) Mutable(fd protoreflect.FieldDescriptor) proto panic(fmt.Errorf("field proposer of message cosmos.gov.v1.Proposal is not mutable")) case "cosmos.gov.v1.Proposal.expedited": panic(fmt.Errorf("field expedited of message cosmos.gov.v1.Proposal is not mutable")) + case "cosmos.gov.v1.Proposal.failed_reason": + panic(fmt.Errorf("field failed_reason of message cosmos.gov.v1.Proposal is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.gov.v1.Proposal")) @@ -1703,6 +1722,8 @@ func (x *fastReflection_Proposal) NewField(fd protoreflect.FieldDescriptor) prot return protoreflect.ValueOfString("") case "cosmos.gov.v1.Proposal.expedited": return protoreflect.ValueOfBool(false) + case "cosmos.gov.v1.Proposal.failed_reason": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.gov.v1.Proposal")) @@ -1829,6 +1850,10 @@ func (x *fastReflection_Proposal) ProtoMethods() *protoiface.Methods { if x.Expedited { n += 2 } + l = len(x.FailedReason) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -1858,6 +1883,13 @@ func (x *fastReflection_Proposal) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.FailedReason) > 0 { + i -= len(x.FailedReason) + copy(dAtA[i:], x.FailedReason) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.FailedReason))) + i-- + dAtA[i] = 0x7a + } if x.Expedited { i-- if x.Expedited { @@ -2491,6 +2523,38 @@ func (x *fastReflection_Proposal) ProtoMethods() *protoiface.Methods { } } x.Expedited = bool(v != 0) + case 15: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field FailedReason", 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.FailedReason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -7136,6 +7200,10 @@ type Proposal struct { // // Since: cosmos-sdk 0.50 Expedited bool `protobuf:"varint,14,opt,name=expedited,proto3" json:"expedited,omitempty"` + // failed_reason defines the reason why the proposal failed + // + // Since: cosmos-sdk 0.50 + FailedReason string `protobuf:"bytes,15,opt,name=failed_reason,json=failedReason,proto3" json:"failed_reason,omitempty"` } func (x *Proposal) Reset() { @@ -7256,6 +7324,13 @@ func (x *Proposal) GetExpedited() bool { return false } +func (x *Proposal) GetFailedReason() string { + if x != nil { + return x.FailedReason + } + return "" +} + // TallyResult defines a standard tally for a governance proposal. type TallyResult struct { state protoimpl.MessageState @@ -7744,7 +7819,7 @@ var file_cosmos_gov_v1_gov_proto_rawDesc = []byte{ 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, - 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xdf, 0x05, 0x0a, + 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x84, 0x06, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, @@ -7790,156 +7865,158 @@ var file_cosmos_gov_v1_gov_proto_rawDesc = []byte{ 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x22, 0xd7, - 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2b, - 0x0a, 0x09, 0x79, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x52, 0x08, 0x79, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x0d, 0x61, - 0x62, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, - 0x6e, 0x74, 0x52, 0x0c, 0x61, 0x62, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x29, 0x0a, 0x08, 0x6e, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, - 0x6e, 0x74, 0x52, 0x07, 0x6e, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x12, 0x6e, - 0x6f, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x76, 0x65, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0f, 0x6e, 0x6f, 0x57, 0x69, 0x74, 0x68, 0x56, - 0x65, 0x74, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb6, 0x01, 0x0a, 0x04, 0x56, 0x6f, 0x74, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, - 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x6f, 0x74, - 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x76, - 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x56, 0x6f, 0x74, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x03, 0x10, - 0x04, 0x22, 0xdd, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x12, 0x59, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x69, 0x6e, 0x42, 0x1d, 0xc8, 0xde, 0x1f, 0x00, 0xea, 0xde, 0x1f, 0x15, 0x6d, 0x69, 0x6e, - 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x2c, 0x6f, 0x6d, 0x69, 0x74, 0x65, 0x6d, 0x70, - 0x74, 0x79, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x12, 0x6d, - 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x70, 0x65, - 0x72, 0x69, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x24, 0xea, 0xde, 0x1f, 0x1c, 0x6d, 0x61, 0x78, 0x5f, 0x64, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x2c, 0x6f, 0x6d, - 0x69, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x98, 0xdf, 0x1f, 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78, - 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x3a, 0x02, 0x18, - 0x01, 0x22, 0x58, 0x0a, 0x0c, 0x56, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x12, 0x44, 0x0a, 0x0d, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x69, - 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x42, 0x04, 0x98, 0xdf, 0x1f, 0x01, 0x52, 0x0c, 0x76, 0x6f, 0x74, 0x69, 0x6e, - 0x67, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x3a, 0x02, 0x18, 0x01, 0x22, 0x9e, 0x01, 0x0a, 0x0b, - 0x54, 0x61, 0x6c, 0x6c, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x71, - 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, - 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x06, 0x71, 0x75, 0x6f, - 0x72, 0x75, 0x6d, 0x12, 0x2c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, - 0x64, 0x12, 0x35, 0x0a, 0x0e, 0x76, 0x65, 0x74, 0x6f, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, - 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x0d, 0x76, 0x65, 0x74, 0x6f, 0x54, - 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xd3, 0x07, 0x0a, - 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x5f, 0x64, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x12, 0x4d, - 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x70, 0x65, - 0x72, 0x69, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0x98, 0xdf, 0x1f, 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78, - 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x44, 0x0a, - 0x0d, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, - 0x04, 0x98, 0xdf, 0x1f, 0x01, 0x52, 0x0c, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, - 0x69, 0x6f, 0x64, 0x12, 0x26, 0x0a, 0x06, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x44, 0x65, 0x63, 0x52, 0x06, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x2c, 0x0a, 0x09, 0x74, - 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, - 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x09, - 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x35, 0x0a, 0x0e, 0x76, 0x65, 0x74, - 0x6f, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, - 0x63, 0x52, 0x0d, 0x76, 0x65, 0x74, 0x6f, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, - 0x12, 0x49, 0x0a, 0x19, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, - 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x12, 0x23, + 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x22, 0xd7, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x2b, 0x0a, 0x09, 0x79, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x08, 0x79, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x33, 0x0a, 0x0d, 0x61, 0x62, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0c, 0x61, 0x62, 0x73, 0x74, 0x61, 0x69, 0x6e, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x08, 0x6e, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x07, 0x6e, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x3b, 0x0a, 0x12, 0x6e, 0x6f, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x76, 0x65, 0x74, 0x6f, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, + 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0f, 0x6e, 0x6f, + 0x57, 0x69, 0x74, 0x68, 0x56, 0x65, 0x74, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb6, 0x01, + 0x0a, 0x04, 0x56, 0x6f, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x72, 0x6f, + 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x52, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x67, 0x6f, 0x76, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, + 0x64, 0x56, 0x6f, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xdd, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x59, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x5f, + 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x1d, 0xc8, 0xde, 0x1f, 0x00, 0xea, 0xde, + 0x1f, 0x15, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x2c, 0x6f, 0x6d, + 0x69, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x44, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x12, 0x6d, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x24, 0xea, 0xde, 0x1f, 0x1c, + 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x2c, 0x6f, 0x6d, 0x69, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x98, 0xdf, 0x1f, 0x01, + 0x52, 0x10, 0x6d, 0x61, 0x78, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x50, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x3a, 0x02, 0x18, 0x01, 0x22, 0x58, 0x0a, 0x0c, 0x56, 0x6f, 0x74, 0x69, 0x6e, 0x67, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x44, 0x0a, 0x0d, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, + 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0x98, 0xdf, 0x1f, 0x01, 0x52, 0x0c, + 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x3a, 0x02, 0x18, 0x01, + 0x22, 0x9e, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x6c, 0x6c, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x26, 0x0a, 0x06, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, + 0x52, 0x06, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x2c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, + 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, + 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x09, 0x74, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x35, 0x0a, 0x0e, 0x76, 0x65, 0x74, 0x6f, 0x5f, 0x74, + 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, + 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x0d, + 0x76, 0x65, 0x74, 0x6f, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x3a, 0x02, 0x18, + 0x01, 0x22, 0xd3, 0x07, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x45, 0x0a, 0x0b, + 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, + 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x44, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x12, 0x4d, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0x98, 0xdf, 0x1f, 0x01, + 0x52, 0x10, 0x6d, 0x61, 0x78, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x50, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x12, 0x44, 0x0a, 0x0d, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, + 0x69, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0x98, 0xdf, 0x1f, 0x01, 0x52, 0x0c, 0x76, 0x6f, 0x74, 0x69, + 0x6e, 0x67, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x26, 0x0a, 0x06, 0x71, 0x75, 0x6f, 0x72, + 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x06, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, + 0x12, 0x2c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x44, 0x65, 0x63, 0x52, 0x16, 0x6d, 0x69, 0x6e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x44, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x42, 0x0a, 0x15, 0x70, - 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x61, 0x6c, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, - 0x4a, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, 0x63, 0x61, 0x6e, 0x63, - 0x65, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, - 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, - 0x6c, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x17, 0x65, - 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x5f, - 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0x98, 0xdf, 0x1f, 0x01, 0x52, 0x15, 0x65, - 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x56, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x65, - 0x72, 0x69, 0x6f, 0x64, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, - 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, - 0x63, 0x52, 0x12, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x54, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x58, 0x0a, 0x15, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, - 0x65, 0x64, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x18, 0x0c, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, - 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x13, 0x65, 0x78, 0x70, 0x65, - 0x64, 0x69, 0x74, 0x65, 0x64, 0x4d, 0x69, 0x6e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x12, - 0x28, 0x0a, 0x10, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x5f, 0x71, 0x75, 0x6f, - 0x72, 0x75, 0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x62, 0x75, 0x72, 0x6e, 0x56, - 0x6f, 0x74, 0x65, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x41, 0x0a, 0x1d, 0x62, 0x75, 0x72, - 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x1a, 0x62, 0x75, 0x72, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x44, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x50, 0x72, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0e, - 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x5f, 0x76, 0x65, 0x74, 0x6f, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x75, 0x72, 0x6e, 0x56, 0x6f, 0x74, 0x65, 0x56, 0x65, - 0x74, 0x6f, 0x2a, 0x89, 0x01, 0x0a, 0x0a, 0x56, 0x6f, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, - 0x0a, 0x0f, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x59, 0x45, - 0x53, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x41, 0x42, 0x53, 0x54, 0x41, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, - 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x10, 0x03, - 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x4e, 0x4f, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x56, 0x45, 0x54, 0x4f, 0x10, 0x04, 0x2a, 0xce, - 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x5f, 0x50, 0x45, - 0x52, 0x49, 0x4f, 0x44, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, - 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x4f, 0x54, 0x49, 0x4e, 0x47, - 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x4f, - 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53, - 0x53, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, - 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, - 0x44, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x42, - 0x99, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, - 0x6f, 0x76, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x47, 0x6f, 0x76, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x67, 0x6f, 0x76, 0x2f, 0x76, - 0x31, 0x3b, 0x67, 0x6f, 0x76, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x47, 0x58, 0xaa, 0x02, 0x0d, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x47, 0x6f, 0x76, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x6f, 0x76, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x6f, 0x76, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x3a, 0x3a, 0x47, 0x6f, 0x76, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x44, 0x65, 0x63, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x35, + 0x0a, 0x0e, 0x76, 0x65, 0x74, 0x6f, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x0d, 0x76, 0x65, 0x74, 0x6f, 0x54, 0x68, 0x72, 0x65, + 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x49, 0x0a, 0x19, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x16, 0x6d, 0x69, 0x6e, 0x49, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x61, 0x74, 0x69, 0x6f, + 0x12, 0x42, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, 0x63, 0x61, 0x6e, + 0x63, 0x65, 0x6c, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, + 0x13, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, + 0x61, 0x74, 0x69, 0x6f, 0x12, 0x4a, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x12, 0x70, 0x72, + 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x74, + 0x12, 0x57, 0x0a, 0x17, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x76, 0x6f, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0x98, 0xdf, + 0x1f, 0x01, 0x52, 0x15, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x56, 0x6f, 0x74, + 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x78, 0x70, + 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x12, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, + 0x64, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x58, 0x0a, 0x15, 0x65, 0x78, + 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x13, 0x65, 0x78, 0x70, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64, 0x4d, 0x69, 0x6e, 0x44, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x6f, 0x74, + 0x65, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x62, 0x75, 0x72, 0x6e, 0x56, 0x6f, 0x74, 0x65, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x41, + 0x0a, 0x1d, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, + 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x62, 0x75, 0x72, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x61, 0x6c, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x50, 0x72, 0x65, 0x76, 0x6f, 0x74, + 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x5f, 0x76, + 0x65, 0x74, 0x6f, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x75, 0x72, 0x6e, 0x56, + 0x6f, 0x74, 0x65, 0x56, 0x65, 0x74, 0x6f, 0x2a, 0x89, 0x01, 0x0a, 0x0a, 0x56, 0x6f, 0x74, 0x65, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, + 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x59, 0x45, 0x53, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x54, 0x45, + 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x42, 0x53, 0x54, 0x41, 0x49, 0x4e, 0x10, + 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x4e, 0x4f, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x4f, 0x50, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x56, 0x45, 0x54, + 0x4f, 0x10, 0x04, 0x2a, 0xce, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, + 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x52, 0x4f, 0x50, 0x4f, + 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x50, 0x4f, 0x53, + 0x49, 0x54, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x50, + 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, + 0x4f, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x10, 0x02, 0x12, 0x1a, + 0x0a, 0x16, 0x50, 0x52, 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, + 0x4f, 0x50, 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, + 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x4f, 0x50, + 0x4f, 0x53, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, + 0x45, 0x44, 0x10, 0x05, 0x42, 0x99, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x76, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x47, 0x6f, 0x76, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, + 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, + 0x67, 0x6f, 0x76, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x6f, 0x76, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, + 0x47, 0x58, 0xaa, 0x02, 0x0d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x47, 0x6f, 0x76, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x0d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x6f, 0x76, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x19, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x6f, 0x76, 0x5c, + 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x0f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x47, 0x6f, 0x76, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/client/v2/go.mod b/client/v2/go.mod index fc8f3c214ce82..a1488e8c8e570 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -25,7 +25,7 @@ require ( cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca // indirect cosmossdk.io/math v1.0.1 // indirect cosmossdk.io/store v1.0.0-alpha.1 // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/client/v2/go.sum b/client/v2/go.sum index d2686e32cff68..be9638d161fe0 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/go.mod b/go.mod index a5c6fd5f61a65..005c14875eca2 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca cosmossdk.io/math v1.0.1 cosmossdk.io/store v1.0.0-alpha.1 - cosmossdk.io/x/tx v0.8.0 + cosmossdk.io/x/tx v0.9.1 github.com/99designs/keyring v1.2.1 github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 github.com/bits-and-blooms/bitset v1.8.0 diff --git a/go.sum b/go.sum index acbbf8d4043c0..390023e7dd818 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/proto/cosmos/gov/v1/gov.proto b/proto/cosmos/gov/v1/gov.proto index 71fed22daff44..8b34e6f63032c 100644 --- a/proto/cosmos/gov/v1/gov.proto +++ b/proto/cosmos/gov/v1/gov.proto @@ -102,6 +102,11 @@ message Proposal { // // Since: cosmos-sdk 0.50 bool expedited = 14; + + // failed_reason defines the reason why the proposal failed + // + // Since: cosmos-sdk 0.50 + string failed_reason = 15; } // ProposalStatus enumerates the valid statuses of a proposal. diff --git a/simapp/go.mod b/simapp/go.mod index d1a10445e0c24..d73f3caa4ad78 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -16,7 +16,7 @@ require ( cosmossdk.io/x/evidence v0.0.0-20230613133644-0a778132a60f cosmossdk.io/x/feegrant v0.0.0-20230613133644-0a778132a60f cosmossdk.io/x/nft v0.0.0-20230613133644-0a778132a60f - cosmossdk.io/x/tx v0.8.0 + cosmossdk.io/x/tx v0.9.1 cosmossdk.io/x/upgrade v0.0.0-20230613133644-0a778132a60f github.com/cometbft/cometbft v0.38.0-rc2 github.com/cosmos/cosmos-db v1.0.0 diff --git a/simapp/go.sum b/simapp/go.sum index 31880e9cc4e68..0da64aeecdecf 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -203,8 +203,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/tests/e2e/authz/grpc.go b/tests/e2e/authz/grpc.go index bebabd79ce0e6..dafa791e25aaa 100644 --- a/tests/e2e/authz/grpc.go +++ b/tests/e2e/authz/grpc.go @@ -200,7 +200,7 @@ func (s *E2ETestSuite) TestQueryGranterGrantsGRPC() { fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.APIAddress, val.Address.String()), false, "", - 7, + 6, }, } for _, tc := range testCases { diff --git a/tests/e2e/authz/query.go b/tests/e2e/authz/query.go deleted file mode 100644 index 183474b7f9605..0000000000000 --- a/tests/e2e/authz/query.go +++ /dev/null @@ -1,269 +0,0 @@ -package authz - -import ( - "fmt" - "strings" - "time" - - "cosmossdk.io/math" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/address" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/cosmos/cosmos-sdk/x/authz/client/cli" - authzclitestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil" -) - -func (s *E2ETestSuite) TestQueryAuthorizations() { - val := s.network.Validators[0] - - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.ClientCtx, - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - testCases := []struct { - name string - args []string - expectErr bool - expErrMsg string - }{ - { - "Error: Invalid grantee", - []string{ - val.Address.String(), - "invalid grantee", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "decoding bech32 failed: invalid character in string: ' '", - }, - { - "Error: Invalid granter", - []string{ - "invalid granter", - grantee.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "decoding bech32 failed: invalid character in string: ' '", - }, - { - "Valid txn (json)", - []string{ - val.Address.String(), - grantee.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - ``, - }, - } - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.GetCmdQueryGrants(address.NewBech32Codec("cosmos")) - clientCtx := val.ClientCtx - resp, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(string(resp.Bytes()), tc.expErrMsg) - } else { - s.Require().NoError(err) - var grants authz.QueryGrantsResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &grants) - s.Require().NoError(err) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryAuthorization() { - val := s.network.Validators[0] - - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.ClientCtx, - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - testCases := []struct { - name string - args []string - expectErr bool - expectedOutput string - }{ - { - "Error: Invalid grantee", - []string{ - val.Address.String(), - "invalid grantee", - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "", - }, - { - "Error: Invalid granter", - []string{ - "invalid granter", - grantee.String(), - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "", - }, - { - "no authorization found", - []string{ - val.Address.String(), - grantee.String(), - "typeMsgSend", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "", - }, - { - "Valid txn (json)", - []string{ - val.Address.String(), - grantee.String(), - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - `{"@type":"/cosmos.bank.v1beta1.SendAuthorization","spend_limit":[{"denom":"stake","amount":"100"}],"allow_list":[]}`, - }, - { - "Valid txn with allowed list (json)", - []string{ - val.Address.String(), - s.grantee[3].String(), - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - fmt.Sprintf(`{"@type":"/cosmos.bank.v1beta1.SendAuthorization","spend_limit":[{"denom":"stake","amount":"88"}],"allow_list":["%s"]}`, s.grantee[4]), - }, - } - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.GetCmdQueryGrants(address.NewBech32Codec("cosmos")) - clientCtx := val.ClientCtx - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().Contains(strings.TrimSpace(out.String()), tc.expectedOutput) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryGranterGrants() { - val := s.network.Validators[0] - grantee := s.grantee[0] - require := s.Require() - - testCases := []struct { - name string - args []string - expectErr bool - expectedErr string - expItems int - }{ - { - "invalid address", - []string{ - "invalid-address", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "decoding bech32 failed", - 0, - }, - { - "no authorization found", - []string{ - grantee.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - 0, - }, - { - "valid case", - []string{ - val.Address.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - 7, - }, - { - "valid case with pagination", - []string{ - val.Address.String(), - "--limit=2", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - 2, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.GetQueryGranterGrants(address.NewBech32Codec("cosmos")) - clientCtx := val.ClientCtx - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - require.Error(err) - require.Contains(out.String(), tc.expectedErr) - } else { - require.NoError(err) - var grants authz.QueryGranterGrantsResponse - require.NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants)) - require.Len(grants.Grants, tc.expItems) - } - }) - } -} diff --git a/tests/go.mod b/tests/go.mod index 639b1d0c2eb0c..2e3712d06983d 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -15,7 +15,7 @@ require ( cosmossdk.io/x/evidence v0.0.0-20230613133644-0a778132a60f cosmossdk.io/x/feegrant v0.0.0-20230613133644-0a778132a60f cosmossdk.io/x/nft v0.0.0-20230613133644-0a778132a60f // indirect - cosmossdk.io/x/tx v0.8.0 + cosmossdk.io/x/tx v0.9.1 cosmossdk.io/x/upgrade v0.0.0-20230613133644-0a778132a60f github.com/cometbft/cometbft v0.38.0-rc2 github.com/cosmos/cosmos-db v1.0.0 diff --git a/tests/go.sum b/tests/go.sum index ef5322ceb2a7f..b3bbad4b0ff82 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -203,8 +203,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/tools/confix/go.mod b/tools/confix/go.mod index 34494e9a0b29a..2ce804717fd03 100644 --- a/tools/confix/go.mod +++ b/tools/confix/go.mod @@ -21,7 +21,7 @@ require ( cosmossdk.io/log v1.1.0 // indirect cosmossdk.io/math v1.0.1 // indirect cosmossdk.io/store v1.0.0-alpha.1 // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/tools/confix/go.sum b/tools/confix/go.sum index 72fae3ae6c260..da43ccd163e08 100644 --- a/tools/confix/go.sum +++ b/tools/confix/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/tools/cosmovisor/CHANGELOG.md b/tools/cosmovisor/CHANGELOG.md index c8557e9833fee..1be2bba581486 100644 --- a/tools/cosmovisor/CHANGELOG.md +++ b/tools/cosmovisor/CHANGELOG.md @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#16413](https://github.com/cosmos/cosmos-sdk/issues/16413) Add `cosmovisor pre-upgrade` command to manually add an upgrade to cosmovisor. * [#16573](https://github.com/cosmos/cosmos-sdk/pull/16573) Extend `cosmovisor` configuration with new log format options * [#16550](https://github.com/cosmos/cosmos-sdk/pull/16550) Add COSMOVISOR_CUSTOM_PREUPGRADE to cosmovisor to execute custom pre-upgrade scripts (separate from daemon pre-upgrade). +* [#16963](https://github.com/cosmos/cosmos-sdk/pull/69630) Add DAEMON_SHUTDOWN_GRACE to send interrupt and wait before sending kill * [#15361](https://github.com/cosmos/cosmos-sdk/pull/15361) Add `cosmovisor config` command to display the configuration used by cosmovisor. ## Improvements diff --git a/tools/cosmovisor/README.md b/tools/cosmovisor/README.md index 46a9d1159d725..b6191307335ab 100644 --- a/tools/cosmovisor/README.md +++ b/tools/cosmovisor/README.md @@ -90,6 +90,7 @@ Use of `cosmovisor` without one of the action arguments is deprecated. For backw * `DAEMON_DOWNLOAD_MUST_HAVE_CHECKSUM` (*optional*, default = `false`), if `true` cosmovisor will require that a checksum is provided in the upgrade plan for the binary to be downloaded. If `false`, cosmovisor will not require a checksum to be provided, but still check the checksum if one is provided. * `DAEMON_RESTART_AFTER_UPGRADE` (*optional*, default = `true`), if `true`, restarts the subprocess with the same command-line arguments and flags (but with the new binary) after a successful upgrade. Otherwise (`false`), `cosmovisor` stops running after an upgrade and requires the system administrator to manually restart it. Note restart is only after the upgrade and does not auto-restart the subprocess after an error occurs. * `DAEMON_RESTART_DELAY` (*optional*, default none), allow a node operator to define a delay between the node halt (for upgrade) and backup by the specified time. The value must be a duration (e.g. `1s`). +* `DAEMON_SHUTDOWN_GRACE` (*optional*, default none), if set, send interrupt to binary and wait the specified time to allow for cleanup/cache flush to disk before sending the kill signal. The value must be a duration (e.g. `1s`). * `DAEMON_POLL_INTERVAL` (*optional*, default 300 milliseconds), is the interval length for polling the upgrade plan file. The value must be a duration (e.g. `1s`). * `DAEMON_DATA_BACKUP_DIR` option to set a custom backup directory. If not set, `DAEMON_HOME` is used. * `UNSAFE_SKIP_BACKUP` (defaults to `false`), if set to `true`, upgrades directly without performing a backup. Otherwise (`false`, default) backs up the data before trying the upgrade. The default value of false is useful and recommended in case of failures and when a backup needed to rollback. We recommend using the default backup option `UNSAFE_SKIP_BACKUP=false`. diff --git a/tools/cosmovisor/args.go b/tools/cosmovisor/args.go index 84a202a045900..4501e8e7d880b 100644 --- a/tools/cosmovisor/args.go +++ b/tools/cosmovisor/args.go @@ -25,6 +25,7 @@ const ( EnvDownloadMustHaveChecksum = "DAEMON_DOWNLOAD_MUST_HAVE_CHECKSUM" EnvRestartUpgrade = "DAEMON_RESTART_AFTER_UPGRADE" EnvRestartDelay = "DAEMON_RESTART_DELAY" + EnvShutdownGrace = "DAEMON_SHUTDOWN_GRACE" EnvSkipBackup = "UNSAFE_SKIP_BACKUP" EnvDataBackupPath = "DAEMON_DATA_BACKUP_DIR" EnvInterval = "DAEMON_POLL_INTERVAL" @@ -51,6 +52,7 @@ type Config struct { DownloadMustHaveChecksum bool RestartAfterUpgrade bool RestartDelay time.Duration + ShutdownGrace time.Duration PollInterval time.Duration UnsafeSkipBackup bool DataBackupPath string @@ -207,6 +209,17 @@ func GetConfigFromEnv() (*Config, error) { } } + cfg.ShutdownGrace = 0 // default value but makes it explicit + shutdownGrace := os.Getenv(EnvShutdownGrace) + if shutdownGrace != "" { + val, err := parseEnvDuration(shutdownGrace) + if err != nil { + errs = append(errs, fmt.Errorf("invalid: %s: %w", EnvShutdownGrace, err)) + } else { + cfg.ShutdownGrace = val + } + } + envPreupgradeMaxRetriesVal := os.Getenv(EnvPreupgradeMaxRetries) if cfg.PreupgradeMaxRetries, err = strconv.Atoi(envPreupgradeMaxRetriesVal); err != nil && envPreupgradeMaxRetriesVal != "" { errs = append(errs, fmt.Errorf("%s could not be parsed to int: %w", EnvPreupgradeMaxRetries, err)) @@ -428,6 +441,7 @@ func (cfg Config) DetailString() string { {EnvDownloadMustHaveChecksum, fmt.Sprintf("%t", cfg.DownloadMustHaveChecksum)}, {EnvRestartUpgrade, fmt.Sprintf("%t", cfg.RestartAfterUpgrade)}, {EnvRestartDelay, cfg.RestartDelay.String()}, + {EnvShutdownGrace, cfg.ShutdownGrace.String()}, {EnvInterval, cfg.PollInterval.String()}, {EnvSkipBackup, fmt.Sprintf("%t", cfg.UnsafeSkipBackup)}, {EnvDataBackupPath, cfg.DataBackupPath}, @@ -436,6 +450,7 @@ func (cfg Config) DetailString() string { {EnvColorLogs, fmt.Sprintf("%t", cfg.ColorLogs)}, {EnvTimeFormatLogs, cfg.TimeFormatLogs}, {EnvCustomPreupgrade, cfg.CustomPreupgrade}, + {EnvDisableRecase, fmt.Sprintf("%t", cfg.DisableRecase)}, } derivedEntries := []struct{ name, value string }{ diff --git a/tools/cosmovisor/args_test.go b/tools/cosmovisor/args_test.go index 399e31925350d..4645a562da943 100644 --- a/tools/cosmovisor/args_test.go +++ b/tools/cosmovisor/args_test.go @@ -39,6 +39,7 @@ type cosmovisorEnv struct { TimeFormatLogs string CustomPreupgrade string DisableRecase string + ShutdownGrace string } type envMap struct { @@ -55,6 +56,7 @@ func (c cosmovisorEnv) ToMap() map[string]envMap { EnvDownloadMustHaveChecksum: {val: c.DownloadMustHaveChecksum, allowEmpty: false}, EnvRestartUpgrade: {val: c.RestartUpgrade, allowEmpty: false}, EnvRestartDelay: {val: c.RestartDelay, allowEmpty: false}, + EnvShutdownGrace: {val: c.ShutdownGrace, allowEmpty: false}, EnvSkipBackup: {val: c.SkipBackup, allowEmpty: false}, EnvDataBackupPath: {val: c.DataBackupPath, allowEmpty: false}, EnvInterval: {val: c.Interval, allowEmpty: false}, @@ -82,6 +84,8 @@ func (c *cosmovisorEnv) Set(envVar, envVal string) { c.RestartUpgrade = envVal case EnvRestartDelay: c.RestartDelay = envVal + case EnvShutdownGrace: + c.ShutdownGrace = envVal case EnvSkipBackup: c.SkipBackup = envVal case EnvDataBackupPath: @@ -101,7 +105,7 @@ func (c *cosmovisorEnv) Set(envVar, envVal string) { case EnvDisableRecase: c.DisableRecase = envVal default: - panic(fmt.Errorf("Unknown environment variable [%s]. Ccannot set field to [%s]. ", envVar, envVal)) + panic(fmt.Errorf("Unknown environment variable [%s]. Cannot set field to [%s]. ", envVar, envVal)) } } @@ -461,6 +465,7 @@ func (s *argsTestSuite) TestGetConfigFromEnv() { timeFormatLogs string, customPreUpgrade string, disableRecase bool, + shutdownGrace int, ) *Config { return &Config{ Home: home, @@ -478,6 +483,7 @@ func (s *argsTestSuite) TestGetConfigFromEnv() { TimeFormatLogs: timeFormatLogs, CustomPreupgrade: customPreUpgrade, DisableRecase: disableRecase, + ShutdownGrace: time.Duration(shutdownGrace), } } @@ -503,19 +509,20 @@ func (s *argsTestSuite) TestGetConfigFromEnv() { TimeFormatLogs: "bad", CustomPreupgrade: "", DisableRecase: "bad", + ShutdownGrace: "bad", }, expectedCfg: nil, - expectedErrCount: 12, + expectedErrCount: 13, }, { name: "all good", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "true"}, - expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", true), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "true", "10s"}, + expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", true, 10000000000), expectedErrCount: 0, }, { name: "nothing set", - envVals: cosmovisorEnv{"", "", "", "", "", "", "", "", "", "", "false", "false", "", "", ""}, + envVals: cosmovisorEnv{"", "", "", "", "", "", "", "", "", "", "false", "false", "", "", "", ""}, expectedCfg: nil, expectedErrCount: 3, }, @@ -523,231 +530,237 @@ func (s *argsTestSuite) TestGetConfigFromEnv() { // timeformat tests are done in the TestTimeFormat { name: "download bin bad", - envVals: cosmovisorEnv{absPath, "testname", "bad", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "", ""}, + envVals: cosmovisorEnv{absPath, "testname", "bad", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "download bin not set", - envVals: cosmovisorEnv{absPath, "testname", "", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "", false), + envVals: cosmovisorEnv{absPath, "testname", "", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "", false, 0), expectedErrCount: 0, }, { name: "download bin true", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "download bin false", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "download ensure checksum true", - envVals: cosmovisorEnv{absPath, "testname", "true", "false", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, false, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "false", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, false, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "restart upgrade bad", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "bad", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "bad", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "restart upgrade not set", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, true, true, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, true, true, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "restart upgrade true", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "true", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, true, true, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "true", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, true, true, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "restart upgrade true", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "skip unsafe backups bad", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "bad", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "bad", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "skip unsafe backups not set", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, true, false, 600, false, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, true, false, 600, false, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "skip unsafe backups true", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "true", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, true, false, 600, true, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "skip unsafe backups false", - envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", true, true, false, 600, false, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "true", "true", "false", "600ms", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", true, true, false, 600, false, absPath, 303, 1, false, true, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "poll interval bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "bad", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "bad", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "poll interval 0", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "0", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "0", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "poll interval not set", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "", "1", "false", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 300, 1, false, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "", "1", "false", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 300, 1, false, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "poll interval 600", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "600", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "600", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "poll interval 1s", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "1s", "1", "false", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 1000, 1, false, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "1s", "1", "false", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 1000, 1, false, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "poll interval -3m", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "-3m", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "-3m", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "restart delay bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "bad", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "bad", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "restart delay 0", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "0", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "0", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "restart delay not set", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "", "false", "", "303ms", "1", "false", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 0, false, absPath, 303, 1, false, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "", "false", "", "303ms", "1", "false", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 0, false, absPath, 303, 1, false, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "restart delay 600", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600", "false", "", "300ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600", "false", "", "300ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "restart delay 1s", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "1s", "false", "", "303ms", "1", "false", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 1000, false, absPath, 303, 1, false, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "1s", "false", "", "303ms", "1", "false", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 1000, false, absPath, 303, 1, false, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "restart delay -3m", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "-3m", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "-3m", "false", "", "303ms", "1", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "prepupgrade max retries bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "bad", "false", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "bad", "false", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "prepupgrade max retries 0", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "0", "false", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, false, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "0", "false", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, false, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "prepupgrade max retries not set", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "false", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, false, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "false", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, false, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "prepupgrade max retries 5", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "5", "false", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 5, false, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "5", "false", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 5, false, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "disable logs bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "5", "bad", "true", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "5", "bad", "true", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "disable logs good", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "disable logs color bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "5", "true", "bad", "kitchen", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "5", "true", "bad", "kitchen", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "disable logs color good", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "false", "kitchen", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, false, time.Kitchen, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "false", "kitchen", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, false, time.Kitchen, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "disable logs timestamp", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "false", "", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, false, "", "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "false", "", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, false, "", "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "enable rf3339 logs timestamp", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "rfc3339", "preupgrade.sh", ""}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, true, time.RFC3339, "preupgrade.sh", false), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "rfc3339", "preupgrade.sh", "", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, true, time.RFC3339, "preupgrade.sh", false, 0), expectedErrCount: 0, }, { name: "invalid logs timestamp format", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "invalid", "preupgrade.sh", ""}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "invalid", "preupgrade.sh", "", ""}, expectedCfg: nil, expectedErrCount: 1, }, { name: "disable recase good", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "rfc3339", "preupgrade.sh", "true"}, - expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, true, time.RFC3339, "preupgrade.sh", true), + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "rfc3339", "preupgrade.sh", "true", ""}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, true, time.RFC3339, "preupgrade.sh", true, 0), expectedErrCount: 0, }, { name: "disable recase bad", - envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "rfc3339", "preupgrade.sh", "bad"}, + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "rfc3339", "preupgrade.sh", "bad", ""}, expectedErrCount: 1, }, + { + name: "shutdown grace good", + envVals: cosmovisorEnv{absPath, "testname", "false", "true", "false", "600ms", "false", "", "406ms", "", "true", "true", "rfc3339", "preupgrade.sh", "true", "15s"}, + expectedCfg: newConfig(absPath, "testname", false, true, false, 600, false, absPath, 406, 0, true, true, time.RFC3339, "preupgrade.sh", true, 15000000000), + expectedErrCount: 0, + }, } for _, tc := range tests { diff --git a/tools/cosmovisor/go.mod b/tools/cosmovisor/go.mod index 07fe31b051ef8..8b94991ea282e 100644 --- a/tools/cosmovisor/go.mod +++ b/tools/cosmovisor/go.mod @@ -23,7 +23,7 @@ require ( cosmossdk.io/errors v1.0.0 // indirect cosmossdk.io/math v1.0.1 // indirect cosmossdk.io/store v1.0.0-alpha.1 // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/tools/cosmovisor/go.sum b/tools/cosmovisor/go.sum index ecc76b38c57ab..6b4e89ec17add 100644 --- a/tools/cosmovisor/go.sum +++ b/tools/cosmovisor/go.sum @@ -203,8 +203,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= cosmossdk.io/x/upgrade v0.0.0-20230614103911-b3da8bb4e801 h1:U0jO59nMqMh3/19ktMy0gCd050k7svcrGJG9Vdrri20= cosmossdk.io/x/upgrade v0.0.0-20230614103911-b3da8bb4e801/go.mod h1:Nqm1dOl9yTTtG+uibprZTQp50rW+pd+XjAYGVQ5+Ojc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= diff --git a/tools/cosmovisor/process.go b/tools/cosmovisor/process.go index 9dcf219b3c4ae..051a3621eb9e0 100644 --- a/tools/cosmovisor/process.go +++ b/tools/cosmovisor/process.go @@ -118,7 +118,33 @@ func (l Launcher) WaitForUpgradeOrExit(cmd *exec.Cmd) (bool, error) { case <-l.fw.MonitorUpdate(currentUpgrade): // upgrade - kill the process and restart l.logger.Info("daemon shutting down in an attempt to restart") - _ = cmd.Process.Kill() + + if l.cfg.ShutdownGrace > 0 { + // Interrupt signal + l.logger.Info("sent interrupt to app, waiting for exit") + _ = cmd.Process.Signal(os.Interrupt) + + // Wait app exit + psChan := make(chan *os.ProcessState) + go func() { + pstate, _ := cmd.Process.Wait() + psChan <- pstate + }() + + // Timeout and kill + select { + case <-psChan: + // Normal Exit + l.logger.Info("app exited normally") + case <-time.After(l.cfg.ShutdownGrace): + l.logger.Info("DAEMON_SHUTDOWN_GRACE exceeded, killing app") + // Kill after grace period + _ = cmd.Process.Kill() + } + } else { + // Default: Immediate app kill + _ = cmd.Process.Kill() + } case err := <-cmdDone: l.fw.Stop() // no error -> command exits normally (eg. short command like `gaiad version`) diff --git a/tools/cosmovisor/process_test.go b/tools/cosmovisor/process_test.go index f9b5137f396a0..2ecea4cb780f8 100644 --- a/tools/cosmovisor/process_test.go +++ b/tools/cosmovisor/process_test.go @@ -149,6 +149,51 @@ func (s *processTestSuite) TestLaunchProcessWithRestartDelay() { } } +// TestPlanShutdownGrace will test upgrades without lower case plan names +func (s *processTestSuite) TestPlanShutdownGrace() { + // binaries from testdata/validate directory + require := s.Require() + home := copyTestData(s.T(), "dontdie") + cfg := &cosmovisor.Config{Home: home, Name: "dummyd", PollInterval: 20, UnsafeSkipBackup: true, ShutdownGrace: 2 * time.Second} + logger := log.NewTestLogger(s.T()).With(log.ModuleKey, "cosmosvisor") + + // should run the genesis binary and produce expected output + stdout, stderr := newBuffer(), newBuffer() + currentBin, err := cfg.CurrentBin() + require.NoError(err) + require.Equal(cfg.GenesisBin(), currentBin) + + launcher, err := cosmovisor.NewLauncher(logger, cfg) + require.NoError(err) + + upgradeFile := cfg.UpgradeInfoFilePath() + + args := []string{"foo", "bar", "1234", upgradeFile} + doUpgrade, err := launcher.Run(args, stdout, stderr) + require.NoError(err) + require.True(doUpgrade) + require.Equal("", stderr.String()) + require.Equal(fmt.Sprintf("Genesis foo bar 1234 %s\nUPGRADE \"Chain2\" NEEDED at height: 49: {}\nWARN Need Flush\nFlushed\n", upgradeFile), stdout.String()) + + // ensure this is upgraded now and produces new output + currentBin, err = cfg.CurrentBin() + require.NoError(err) + + require.Equal(cfg.UpgradeBin("chain2"), currentBin) + args = []string{"second", "run", "--verbose"} + stdout.Reset() + stderr.Reset() + + doUpgrade, err = launcher.Run(args, stdout, stderr) + require.NoError(err) + require.False(doUpgrade) + require.Equal("", stderr.String()) + require.Equal("Chain 2 is live!\nArgs: second run --verbose\nFinished successfully\n", stdout.String()) + + // ended without other upgrade + require.Equal(cfg.UpgradeBin("chain2"), currentBin) +} + // TestLaunchProcess will try running the script a few times and watch upgrades work properly // and args are passed through func (s *processTestSuite) TestLaunchProcessWithDownloads() { diff --git a/tools/cosmovisor/testdata/dontdie/cosmovisor/genesis/bin/dummyd b/tools/cosmovisor/testdata/dontdie/cosmovisor/genesis/bin/dummyd new file mode 100755 index 0000000000000..49e60a1e206d5 --- /dev/null +++ b/tools/cosmovisor/testdata/dontdie/cosmovisor/genesis/bin/dummyd @@ -0,0 +1,17 @@ +#!/bin/sh + + +warn() { + echo "WARN Need Flush" +} + +trap warn INT +echo Genesis $@ +sleep 1 +test -z $4 && exit 1001 +echo 'UPGRADE "Chain2" NEEDED at height: 49: {}' +echo '{"name":"Chain2","height":49,"info":""}' > $4 +sleep 1 +echo 'Flushed' +sleep 1 +echo Did not kill in time. Never should be printed!!! diff --git a/tools/cosmovisor/testdata/dontdie/cosmovisor/upgrades/chain2/bin/dummyd b/tools/cosmovisor/testdata/dontdie/cosmovisor/upgrades/chain2/bin/dummyd new file mode 100755 index 0000000000000..0022b84af2920 --- /dev/null +++ b/tools/cosmovisor/testdata/dontdie/cosmovisor/upgrades/chain2/bin/dummyd @@ -0,0 +1,6 @@ +#!/bin/sh + +echo Chain 2 is live! +echo Args: $@ +sleep 1 +echo Finished successfully diff --git a/tools/cosmovisor/testdata/dontdie/data/.gitkeep b/tools/cosmovisor/testdata/dontdie/data/.gitkeep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tools/hubl/go.mod b/tools/hubl/go.mod index 9a8b63cde87fa..258f945982860 100644 --- a/tools/hubl/go.mod +++ b/tools/hubl/go.mod @@ -22,7 +22,7 @@ require ( cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca // indirect cosmossdk.io/math v1.0.1 // indirect cosmossdk.io/store v1.0.0-alpha.1 // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/tools/hubl/go.sum b/tools/hubl/go.sum index 58ff105ab52cc..e9ae65eaf0d66 100644 --- a/tools/hubl/go.sum +++ b/tools/hubl/go.sum @@ -53,8 +53,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/tools/rosetta/go.mod b/tools/rosetta/go.mod index 0569ac0468f0f..312de7221bc4a 100644 --- a/tools/rosetta/go.mod +++ b/tools/rosetta/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( cosmossdk.io/log v1.1.0 cosmossdk.io/math v1.0.1 - cosmossdk.io/x/tx v0.8.0 + cosmossdk.io/x/tx v0.9.1 github.com/coinbase/rosetta-sdk-go/types v1.0.0 github.com/cometbft/cometbft v0.38.0-rc2 github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230614103911-b3da8bb4e801 diff --git a/tools/rosetta/go.sum b/tools/rosetta/go.sum index 83fc27f8d0ab5..2246fb899dc2f 100644 --- a/tools/rosetta/go.sum +++ b/tools/rosetta/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/types/query/collections_pagination.go b/types/query/collections_pagination.go index 4ef389038dc6e..47ca6d5fbb743 100644 --- a/types/query/collections_pagination.go +++ b/types/query/collections_pagination.go @@ -35,24 +35,40 @@ type Collection[K, V any] interface { KeyCodec() collcodec.KeyCodec[K] } -// CollectionPaginate follows the same behavior as Paginate but works on a Collection. -func CollectionPaginate[K, V any, C Collection[K, V]]( +// CollectionPaginate follows the same logic as Paginate but for collection types. +// transformFunc is used to transform the result to a different type. +func CollectionPaginate[K, V any, C Collection[K, V], T any]( ctx context.Context, coll C, pageReq *PageRequest, -) ([]collections.KeyValue[K, V], *PageResponse, error) { - return CollectionFilteredPaginate[K, V](ctx, coll, pageReq, nil) + transformFunc func(key K, value V) (T, error), + opts ...func(opt *CollectionsPaginateOptions[K]), +) ([]T, *PageResponse, error) { + return CollectionFilteredPaginate( + ctx, + coll, + pageReq, + nil, + transformFunc, + opts..., + ) } -// CollectionFilteredPaginate works in the same way as FilteredPaginate but for collection types. +// CollectionFilteredPaginate works in the same way as CollectionPaginate but allows to filter +// results using a predicateFunc. // A nil predicateFunc means no filtering is applied and results are collected as is. -func CollectionFilteredPaginate[K, V any, C Collection[K, V]]( +// TransformFunc is applied only to results which are in range of the pagination and allow +// to convert the result to a different type. +// NOTE: do not collect results using the values/keys passed to predicateFunc as they are not +// guaranteed to be in the pagination range requested. +func CollectionFilteredPaginate[K, V any, C Collection[K, V], T any]( ctx context.Context, coll C, pageReq *PageRequest, predicateFunc func(key K, value V) (include bool, err error), + transformFunc func(key K, value V) (T, error), opts ...func(opt *CollectionsPaginateOptions[K]), -) ([]collections.KeyValue[K, V], *PageResponse, error) { +) (results []T, pageRes *PageResponse, err error) { pageReq = initPageRequestDefaults(pageReq) offset := pageReq.Offset @@ -65,12 +81,6 @@ func CollectionFilteredPaginate[K, V any, C Collection[K, V]]( return nil, nil, fmt.Errorf("invalid request, either offset or key is expected, got both") } - var ( - results []collections.KeyValue[K, V] - pageRes *PageResponse - err error - ) - opt := new(CollectionsPaginateOptions[K]) for _, o := range opts { o(opt) @@ -85,9 +95,9 @@ func CollectionFilteredPaginate[K, V any, C Collection[K, V]]( } if len(key) != 0 { - results, pageRes, err = collFilteredPaginateByKey(ctx, coll, prefix, key, reverse, limit, predicateFunc) + results, pageRes, err = collFilteredPaginateByKey(ctx, coll, prefix, key, reverse, limit, predicateFunc, transformFunc) } else { - results, pageRes, err = collFilteredPaginateNoKey(ctx, coll, prefix, reverse, offset, limit, countTotal, predicateFunc) + results, pageRes, err = collFilteredPaginateNoKey(ctx, coll, prefix, reverse, offset, limit, countTotal, predicateFunc, transformFunc) } // invalid iter error is ignored to retain Paginate behavior if errors.Is(err, collections.ErrInvalidIterator) { @@ -102,7 +112,7 @@ func CollectionFilteredPaginate[K, V any, C Collection[K, V]]( // collFilteredPaginateNoKey applies the provided pagination on the collection when the starting key is not set. // If predicateFunc is nil no filtering is applied. -func collFilteredPaginateNoKey[K, V any, C Collection[K, V]]( +func collFilteredPaginateNoKey[K, V any, C Collection[K, V], T any]( ctx context.Context, coll C, prefix []byte, @@ -111,7 +121,8 @@ func collFilteredPaginateNoKey[K, V any, C Collection[K, V]]( limit uint64, countTotal bool, predicateFunc func(K, V) (bool, error), -) ([]collections.KeyValue[K, V], *PageResponse, error) { + transformFunc func(K, V) (T, error), +) ([]T, *PageResponse, error) { iterator, err := getCollIter[K, V](ctx, coll, prefix, nil, reverse) if err != nil { return nil, nil, err @@ -125,7 +136,7 @@ func collFilteredPaginateNoKey[K, V any, C Collection[K, V]]( var ( count uint64 nextKey []byte - results []collections.KeyValue[K, V] + results []T ) for ; iterator.Valid(); iterator.Next() { @@ -138,7 +149,13 @@ func collFilteredPaginateNoKey[K, V any, C Collection[K, V]]( } // if no predicate function is specified then we just include the result if predicateFunc == nil { - results = append(results, kv) + transformed, err := transformFunc(kv.Key, kv.Value) + if err != nil { + return nil, nil, err + } + results = append(results, transformed) + count++ + // if predicate function is defined we check if the result matches the filtering criteria } else { include, err := predicateFunc(kv.Key, kv.Value) @@ -146,10 +163,14 @@ func collFilteredPaginateNoKey[K, V any, C Collection[K, V]]( return nil, nil, err } if include { - results = append(results, kv) + transformed, err := transformFunc(kv.Key, kv.Value) + if err != nil { + return nil, nil, err + } + results = append(results, transformed) + count++ } } - count++ // second case, we found all the objects specified within the limit case count == limit: key, err := iterator.Key() @@ -172,12 +193,31 @@ func collFilteredPaginateNoKey[K, V any, C Collection[K, V]]( // but we need to count how many possible results exist in total. // so we keep increasing the count until the iterator is fully consumed. case count > limit: - count++ + if predicateFunc == nil { + count++ + + // if predicate function is defined we check if the result matches the filtering criteria + } else { + kv, err := iterator.KeyValue() + if err != nil { + return nil, nil, err + } + + include, err := predicateFunc(kv.Key, kv.Value) + if err != nil { + return nil, nil, err + } + if include { + count++ + } + } } } + resp := &PageResponse{ NextKey: nextKey, } + if countTotal { resp.Total = count + offset } @@ -200,15 +240,16 @@ func advanceIter[I interface { // collFilteredPaginateByKey paginates a collection when a starting key // is provided in the PageRequest. Predicate is applied only if not nil. -func collFilteredPaginateByKey[K, V any, C Collection[K, V]]( +func collFilteredPaginateByKey[K, V any, C Collection[K, V], T any]( ctx context.Context, coll C, prefix []byte, key []byte, reverse bool, limit uint64, - predicateFunc func(K, V) (bool, error), -) ([]collections.KeyValue[K, V], *PageResponse, error) { + predicateFunc func(key K, value V) (bool, error), + transformFunc func(key K, value V) (transformed T, err error), +) (results []T, pageRes *PageResponse, err error) { iterator, err := getCollIter[K, V](ctx, coll, prefix, key, reverse) if err != nil { return nil, nil, err @@ -218,7 +259,6 @@ func collFilteredPaginateByKey[K, V any, C Collection[K, V]]( var ( count uint64 nextKey []byte - results []collections.KeyValue[K, V] ) for ; iterator.Valid(); iterator.Next() { @@ -243,7 +283,11 @@ func collFilteredPaginateByKey[K, V any, C Collection[K, V]]( } // if no predicate is specified then we just append the result if predicateFunc == nil { - results = append(results, kv) + transformed, err := transformFunc(kv.Key, kv.Value) + if err != nil { + return nil, nil, err + } + results = append(results, transformed) // if predicate is applied we execute the predicate function // and append only if predicateFunc yields true. } else { @@ -252,7 +296,11 @@ func collFilteredPaginateByKey[K, V any, C Collection[K, V]]( return nil, nil, err } if include { - results = append(results, kv) + transformed, err := transformFunc(kv.Key, kv.Value) + if err != nil { + return nil, nil, err + } + results = append(results, transformed) } } count++ diff --git a/types/query/collections_pagination_test.go b/types/query/collections_pagination_test.go index cbd3cd0b736e5..874722d4de405 100644 --- a/types/query/collections_pagination_test.go +++ b/types/query/collections_pagination_test.go @@ -100,7 +100,7 @@ func TestCollectionPagination(t *testing.T) { Limit: 3, }, expResp: &PageResponse{ - NextKey: encodeKey(3), + NextKey: encodeKey(5), }, filter: func(key, value uint64) (bool, error) { return key%2 == 0, nil @@ -108,6 +108,7 @@ func TestCollectionPagination(t *testing.T) { expResults: []collections.KeyValue[uint64, uint64]{ {Key: 0, Value: 0}, {Key: 2, Value: 2}, + {Key: 4, Value: 4}, }, }, "filtered with key": { @@ -131,7 +132,15 @@ func TestCollectionPagination(t *testing.T) { for name, tc := range tcs { tc := tc t.Run(name, func(t *testing.T) { - gotResults, gotResponse, err := CollectionFilteredPaginate(ctx, m, tc.req, tc.filter) + gotResults, gotResponse, err := CollectionFilteredPaginate( + ctx, + m, + tc.req, + tc.filter, + func(key, value uint64) (collections.KeyValue[uint64, uint64], error) { + return collections.KeyValue[uint64, uint64]{Key: key, Value: value}, nil + }, + ) if tc.wantErr != nil { require.ErrorIs(t, err, tc.wantErr) return diff --git a/x/auth/keeper/grpc_query.go b/x/auth/keeper/grpc_query.go index f348131ca3adb..1b40d3c3b38c0 100644 --- a/x/auth/keeper/grpc_query.go +++ b/x/auth/keeper/grpc_query.go @@ -47,15 +47,14 @@ func (s queryServer) Accounts(ctx context.Context, req *types.QueryAccountsReque return nil, status.Error(codes.InvalidArgument, "empty request") } - var accounts []*codectypes.Any - _, pageRes, err := query.CollectionFilteredPaginate(ctx, s.k.Accounts, req.Pagination, func(_ sdk.AccAddress, value sdk.AccountI) (include bool, err error) { - accountAny, err := codectypes.NewAnyWithValue(value) - if err != nil { - return false, err - } - accounts = append(accounts, accountAny) - return false, nil // we don't include it since we're already appending the account - }) + accounts, pageRes, err := query.CollectionPaginate( + ctx, + s.k.Accounts, + req.Pagination, + func(_ sdk.AccAddress, value sdk.AccountI) (*codectypes.Any, error) { + return codectypes.NewAnyWithValue(value) + }, + ) return &types.QueryAccountsResponse{Accounts: accounts, Pagination: pageRes}, err } diff --git a/x/authz/client/cli/query.go b/x/authz/client/cli/query.go deleted file mode 100644 index 0ae13f73cbc84..0000000000000 --- a/x/authz/client/cli/query.go +++ /dev/null @@ -1,195 +0,0 @@ -package cli - -import ( - "fmt" - "strings" - - "github.com/spf13/cobra" - - "cosmossdk.io/core/address" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/authz" - bank "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -// GetQueryCmd returns the cli query commands for this module -func GetQueryCmd(ac address.Codec) *cobra.Command { - authorizationQueryCmd := &cobra.Command{ - Use: authz.ModuleName, - Short: "Querying commands for the authz module", - Long: "", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - authorizationQueryCmd.AddCommand( - GetCmdQueryGrants(ac), - GetQueryGranterGrants(ac), - GetQueryGranteeGrants(ac), - ) - - return authorizationQueryCmd -} - -// GetCmdQueryGrants implements the query authorization command. -func GetCmdQueryGrants(ac address.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "grants [granter-addr] [grantee-addr] [msg-type-url]?", - Args: cobra.RangeArgs(2, 3), - Short: "query grants for a granter-grantee pair and optionally a msg-type-url", - Long: strings.TrimSpace( - fmt.Sprintf(`Query authorization grants for a granter-grantee pair. If msg-type-url -is set, it will select grants only for that msg type. -Examples: -$ %s query %s grants cosmos1skj.. cosmos1skjwj.. -$ %s query %s grants cosmos1skjw.. cosmos1skjwj.. %s -`, - version.AppName, authz.ModuleName, - version.AppName, authz.ModuleName, bank.SendAuthorization{}.MsgTypeURL()), - ), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := authz.NewQueryClient(clientCtx) - - _, err = ac.StringToBytes(args[0]) - if err != nil { - return err - } - _, err = ac.StringToBytes(args[1]) - if err != nil { - return err - } - msgAuthorized := "" - if len(args) == 3 { - msgAuthorized = args[2] - } - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.Grants( - cmd.Context(), - &authz.QueryGrantsRequest{ - Granter: args[0], - Grantee: args[1], - MsgTypeUrl: msgAuthorized, - Pagination: pageReq, - }, - ) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "grants") - return cmd -} - -// GetQueryGranterGrants returns cmd to query for all grants for a granter. -func GetQueryGranterGrants(ac address.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "grants-by-granter [granter-addr]", - Args: cobra.ExactArgs(1), - Short: "query authorization grants granted by granter", - Long: strings.TrimSpace( - fmt.Sprintf(`Query authorization grants granted by granter. -Examples: -$ %s q %s grants-by-granter cosmos1skj.. -`, - version.AppName, authz.ModuleName), - ), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - _, err = ac.StringToBytes(args[0]) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := authz.NewQueryClient(clientCtx) - res, err := queryClient.GranterGrants( - cmd.Context(), - &authz.QueryGranterGrantsRequest{ - Granter: args[0], - Pagination: pageReq, - }, - ) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "granter-grants") - return cmd -} - -// GetQueryGranteeGrants returns cmd to query for all grants for a grantee. -func GetQueryGranteeGrants(ac address.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "grants-by-grantee [grantee-addr]", - Args: cobra.ExactArgs(1), - Short: "query authorization grants granted to a grantee", - Long: strings.TrimSpace( - fmt.Sprintf(`Query authorization grants granted to a grantee. -Examples: -$ %s q %s grants-by-grantee cosmos1skj.. -`, - version.AppName, authz.ModuleName), - ), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - _, err = ac.StringToBytes(args[0]) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := authz.NewQueryClient(clientCtx) - res, err := queryClient.GranteeGrants( - cmd.Context(), - &authz.QueryGranteeGrantsRequest{ - Grantee: args[0], - Pagination: pageReq, - }, - ) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "grantee-grants") - return cmd -} diff --git a/x/authz/client/cli/query_test.go b/x/authz/client/cli/query_test.go deleted file mode 100644 index 51b28a04b2f81..0000000000000 --- a/x/authz/client/cli/query_test.go +++ /dev/null @@ -1,315 +0,0 @@ -package cli_test - -import ( - "fmt" - "time" - - sdkmath "cosmossdk.io/math" - - "github.com/cosmos/cosmos-sdk/client/flags" - addresscodec "github.com/cosmos/cosmos-sdk/codec/address" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/cosmos/cosmos-sdk/x/authz/client/cli" - authzclitestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil" -) - -func (s *CLITestSuite) TestQueryAuthorizations() { - val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - s.clientCtx, - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - - testCases := []struct { - name string - args []string - expectErr bool - expErrMsg string - }{ - { - "Error: Invalid grantee", - []string{ - val[0].Address.String(), - "invalid grantee", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "decoding bech32 failed: invalid character in string: ' '", - }, - { - "Error: Invalid granter", - []string{ - "invalid granter", - grantee.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "decoding bech32 failed: invalid character in string: ' '", - }, - { - "Valid txn (json)", - []string{ - val[0].Address.String(), - grantee.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - ``, - }, - } - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.GetCmdQueryGrants(addresscodec.NewBech32Codec("cosmos")) - resp, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(string(resp.Bytes()), tc.expErrMsg) - } else { - s.Require().NoError(err) - var grants authz.QueryGrantsResponse - err = s.clientCtx.Codec.UnmarshalJSON(resp.Bytes(), &grants) - s.Require().NoError(err) - } - }) - } -} - -func (s *CLITestSuite) TestQueryAuthorization() { - val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - s.clientCtx, - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - - testCases := []struct { - name string - args []string - expectErr bool - }{ - { - "Error: Invalid grantee", - []string{ - val[0].Address.String(), - "invalid grantee", - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - }, - { - "Error: Invalid granter", - []string{ - "invalid granter", - grantee.String(), - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - }, - { - "Valid txn (json)", - []string{ - val[0].Address.String(), - grantee.String(), - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - }, - { - "Valid txn with allowed list (json)", - []string{ - val[0].Address.String(), - s.grantee[3].String(), - typeMsgSend, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - }, - } - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.GetCmdQueryGrants(addresscodec.NewBech32Codec("cosmos")) - _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - } - }) - } -} - -func (s *CLITestSuite) TestQueryGranteeGrants() { - val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - require := s.Require() - - _, err := authzclitestutil.CreateGrant( - s.clientCtx, - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - - testCases := []struct { - name string - args []string - expectErr bool - expectedErr string - }{ - { - "invalid address", - []string{ - "invalid-address", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "decoding bech32 failed", - }, - { - "valid case", - []string{ - grantee.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - }, - { - "valid case with pagination", - []string{ - grantee.String(), - "--limit=2", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.GetQueryGranteeGrants(addresscodec.NewBech32Codec("cosmos")) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) - if tc.expectErr { - require.Error(err) - require.Contains(out.String(), tc.expectedErr) - } else { - require.NoError(err) - var grants authz.QueryGranteeGrantsResponse - require.NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants)) - } - }) - } -} - -func (s *CLITestSuite) TestQueryGranterGrants() { - val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - grantee := s.grantee[0] - require := s.Require() - - testCases := []struct { - name string - args []string - expectErr bool - expectedErr string - }{ - { - "invalid address", - []string{ - "invalid-address", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - "decoding bech32 failed", - }, - { - "no authorization found", - []string{ - grantee.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - }, - { - "valid case", - []string{ - val[0].Address.String(), - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - }, - { - "valid case with pagination", - []string{ - val[0].Address.String(), - "--limit=2", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - "", - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.GetQueryGranterGrants(addresscodec.NewBech32Codec("cosmos")) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) - if tc.expectErr { - require.Error(err) - require.Contains(out.String(), tc.expectedErr) - } else { - require.NoError(err) - var grants authz.QueryGranterGrantsResponse - require.NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants)) - } - }) - } -} diff --git a/x/authz/keeper/grpc_query_test.go b/x/authz/keeper/grpc_query_test.go index 1a26e170c586b..00d16f96381a6 100644 --- a/x/authz/keeper/grpc_query_test.go +++ b/x/authz/keeper/grpc_query_test.go @@ -57,7 +57,19 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() { func(require *require.Assertions, res *authz.QueryGrantsResponse) {}, }, { - "Success", + "authorization not found", + func(require *require.Assertions) { + req = &authz.QueryGrantsRequest{ + Granter: addrs[1].String(), + Grantee: addrs[0].String(), + MsgTypeUrl: banktypes.SendAuthorization{}.MsgTypeURL(), + } + }, + "authorization not found for /cosmos.bank.v1beta1.MsgSend", + func(require *require.Assertions, res *authz.QueryGrantsResponse) {}, + }, + { + "success", func(require *require.Assertions) { expAuthorization = suite.createSendAuthorization(addrs[0], addrs[1]) req = &authz.QueryGrantsRequest{ @@ -76,6 +88,28 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() { require.Equal(auth.String(), expAuthorization.String()) }, }, + { + "success with allow list", + func(require *require.Assertions) { + expAuthorization = suite.createSendAuthorizationWithAllowList(addrs[0], addrs[1]) + require.Len(expAuthorization.(*banktypes.SendAuthorization).GetAllowList(), 1) + req = &authz.QueryGrantsRequest{ + Granter: addrs[1].String(), + Grantee: addrs[0].String(), + MsgTypeUrl: expAuthorization.MsgTypeURL(), + } + }, + "", + func(require *require.Assertions, res *authz.QueryGrantsResponse) { + var auth authz.Authorization + require.Equal(1, len(res.Grants)) + err := suite.encCfg.InterfaceRegistry.UnpackAny(res.Grants[0].Authorization, &auth) + require.NoError(err) + require.NotNil(auth) + require.Equal(auth.String(), expAuthorization.String()) + require.Equal(auth.(*banktypes.SendAuthorization).GetAllowList(), expAuthorization.(*banktypes.SendAuthorization).GetAllowList()) + }, + }, } for _, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { @@ -93,70 +127,6 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() { } } -func (suite *TestSuite) TestGRPCQueryAuthorizations() { - queryClient, addrs := suite.queryClient, suite.addrs - var ( - req *authz.QueryGrantsRequest - expAuthorization authz.Authorization - ) - testCases := []struct { - msg string - malleate func() - expPass bool - postTest func(res *authz.QueryGrantsResponse) - }{ - { - "fail invalid granter addr", - func() { - req = &authz.QueryGrantsRequest{} - }, - false, - func(res *authz.QueryGrantsResponse) {}, - }, - { - "fail invalid grantee addr", - func() { - req = &authz.QueryGrantsRequest{ - Granter: addrs[0].String(), - } - }, - false, - func(res *authz.QueryGrantsResponse) {}, - }, - { - "Success", - func() { - expAuthorization = suite.createSendAuthorization(addrs[0], addrs[1]) - req = &authz.QueryGrantsRequest{ - Granter: addrs[1].String(), - Grantee: addrs[0].String(), - } - }, - true, - func(res *authz.QueryGrantsResponse) { - var auth authz.Authorization - suite.Require().Equal(1, len(res.Grants)) - err := suite.encCfg.InterfaceRegistry.UnpackAny(res.Grants[0].Authorization, &auth) - suite.Require().NoError(err) - suite.Require().NotNil(auth) - suite.Require().Equal(auth.String(), expAuthorization.String()) - }, - }, - } - for _, testCase := range testCases { - suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() { - testCase.malleate() - result, err := queryClient.Grants(gocontext.Background(), req) - if testCase.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - testCase.postTest(result) - }) - } -} - func (suite *TestSuite) TestGRPCQueryGranterGrants() { require := suite.Require() queryClient, addrs := suite.queryClient, suite.addrs @@ -312,3 +282,12 @@ func (suite *TestSuite) createSendAuthorization(grantee, granter sdk.AccAddress) suite.Require().NoError(err) return authorization } + +func (suite *TestSuite) createSendAuthorizationWithAllowList(grantee, granter sdk.AccAddress) authz.Authorization { + exp := suite.ctx.BlockHeader().Time.Add(time.Hour) + newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100)) + authorization := &banktypes.SendAuthorization{SpendLimit: newCoins, AllowList: []string{suite.addrs[5].String()}} + err := suite.authzKeeper.SaveGrant(suite.ctx, grantee, granter, authorization, &exp) + suite.Require().NoError(err) + return authorization +} diff --git a/x/authz/module/autocli.go b/x/authz/module/autocli.go new file mode 100644 index 0000000000000..76c3cce25e270 --- /dev/null +++ b/x/authz/module/autocli.go @@ -0,0 +1,53 @@ +package authz + +import ( + "fmt" + + authzv1beta1 "cosmossdk.io/api/cosmos/authz/v1beta1" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + + "github.com/cosmos/cosmos-sdk/version" + bank "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { + return &autocliv1.ModuleOptions{ + Query: &autocliv1.ServiceCommandDescriptor{ + Service: authzv1beta1.Query_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Grants", + Use: "grants [granter-addr] [grantee-addr] ", + Short: "Query grants for a granter-grantee pair and optionally a msg-type-url", + Long: "Query authorization grants for a granter-grantee pair. If msg-type-url is set, it will select grants only for that msg type.", + Example: fmt.Sprintf("%s query authz grants cosmos1skj.. cosmos1skjwj.. %s", version.AppName, bank.SendAuthorization{}.MsgTypeURL()), + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "granter"}, + {ProtoField: "grantee"}, + {ProtoField: "msg_type_url", Optional: true}, + }, + }, + { + RpcMethod: "GranterGrants", + Use: "grants-by-granter [granter-addr]", + Short: "Query authorization grants granted by granter", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "granter"}, + }, + }, + { + RpcMethod: "GranteeGrants", + Use: "grants-by-grantee [grantee-addr]", + Short: "Query authorization grants granted to a grantee", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "grantee"}, + }, + }, + }, + }, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: authzv1beta1.Msg_ServiceDesc.ServiceName, + }, + } +} diff --git a/x/authz/module/module.go b/x/authz/module/module.go index 2450ae8f80b6a..ac0c571ca0e91 100644 --- a/x/authz/module/module.go +++ b/x/authz/module/module.go @@ -90,11 +90,6 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux } } -// GetQueryCmd returns the cli query commands for the authz module -func (ab AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd(ab.ac) -} - // GetTxCmd returns the transaction commands for the authz module func (ab AppModuleBasic) GetTxCmd() *cobra.Command { return cli.GetTxCmd(ab.ac) diff --git a/x/bank/keeper/grpc_query.go b/x/bank/keeper/grpc_query.go index 086f105664e12..010525e5d415f 100644 --- a/x/bank/keeper/grpc_query.go +++ b/x/bank/keeper/grpc_query.go @@ -60,19 +60,20 @@ func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalances } sdkCtx := sdk.UnwrapSDKContext(ctx) - - balances := sdk.NewCoins() - - _, pageRes, err := query.CollectionFilteredPaginate(ctx, k.Balances, req.Pagination, func(key collections.Pair[sdk.AccAddress, string], value math.Int) (include bool, err error) { - denom := key.K2() - if req.ResolveDenom { - if metadata, ok := k.GetDenomMetaData(sdkCtx, denom); ok { - denom = metadata.Display + balances, pageRes, err := query.CollectionPaginate( + ctx, + k.Balances, + req.Pagination, + func(key collections.Pair[sdk.AccAddress, string], value math.Int) (sdk.Coin, error) { + if req.ResolveDenom { + if metadata, ok := k.GetDenomMetaData(sdkCtx, key.K2()); ok { + return sdk.NewCoin(metadata.Display, value), nil + } } - } - balances = append(balances, sdk.NewCoin(denom, value)) - return false, nil // we don't include results because we're appending them here. - }, query.WithCollectionPaginationPairPrefix[sdk.AccAddress, string](addr)) + return sdk.NewCoin(key.K2(), value), nil + }, + query.WithCollectionPaginationPairPrefix[sdk.AccAddress, string](addr), + ) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err) } @@ -94,12 +95,10 @@ func (k BaseKeeper) SpendableBalances(ctx context.Context, req *types.QuerySpend sdkCtx := sdk.UnwrapSDKContext(ctx) - balances := sdk.NewCoins() zeroAmt := math.ZeroInt() - _, pageRes, err := query.CollectionFilteredPaginate(ctx, k.Balances, req.Pagination, func(key collections.Pair[sdk.AccAddress, string], _ math.Int) (include bool, err error) { - balances = append(balances, sdk.NewCoin(key.K2(), zeroAmt)) - return false, nil // not including results as they're appended here + balances, pageRes, err := query.CollectionPaginate(ctx, k.Balances, req.Pagination, func(key collections.Pair[sdk.AccAddress, string], _ math.Int) (coin sdk.Coin, err error) { + return sdk.NewCoin(key.K2(), zeroAmt), nil }, query.WithCollectionPaginationPairPrefix[sdk.AccAddress, string](addr)) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err) @@ -280,19 +279,16 @@ func (k BaseKeeper) DenomOwners( return nil, status.Error(codes.InvalidArgument, err.Error()) } - var denomOwners []*types.DenomOwner - - _, pageRes, err := query.CollectionFilteredPaginate(goCtx, k.Balances.Indexes.Denom, req.Pagination, - func(key collections.Pair[string, sdk.AccAddress], value collections.NoValue) (include bool, err error) { + denomOwners, pageRes, err := query.CollectionPaginate( + goCtx, + k.Balances.Indexes.Denom, + req.Pagination, + func(key collections.Pair[string, sdk.AccAddress], value collections.NoValue) (*types.DenomOwner, error) { amt, err := k.Balances.Get(goCtx, collections.Join(key.K2(), req.Denom)) if err != nil { - return false, err + return nil, err } - denomOwners = append(denomOwners, &types.DenomOwner{ - Address: key.K2().String(), - Balance: sdk.NewCoin(req.Denom, amt), - }) - return false, nil + return &types.DenomOwner{Address: key.K2().String(), Balance: sdk.NewCoin(req.Denom, amt)}, nil }, query.WithCollectionPaginationPairPrefix[string, sdk.AccAddress](req.Denom), ) @@ -316,16 +312,17 @@ func (k BaseKeeper) SendEnabled(goCtx context.Context, req *types.QuerySendEnabl } } } else { - results, pageResp, err := query.CollectionPaginate[string, bool](ctx, k.BaseViewKeeper.SendEnabled, req.Pagination) + results, pageResp, err := query.CollectionPaginate( + ctx, + k.BaseViewKeeper.SendEnabled, + req.Pagination, func(key string, value bool) (*types.SendEnabled, error) { + return types.NewSendEnabled(key, value), nil + }, + ) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } - for _, r := range results { - resp.SendEnabled = append(resp.SendEnabled, &types.SendEnabled{ - Denom: r.Key, - Enabled: r.Value, - }) - } + resp.SendEnabled = results resp.Pagination = pageResp } diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index 4c9b63e07c258..cb0787a5addcb 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -69,14 +69,12 @@ type MintingRestrictionFn func(ctx context.Context, coins sdk.Coins) error // GetPaginatedTotalSupply queries for the supply, ignoring 0 coins, with a given pagination func (k BaseKeeper) GetPaginatedTotalSupply(ctx context.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error) { - results, pageResp, err := query.CollectionPaginate[string, math.Int](ctx, k.Supply, pagination) + coins, pageResp, err := query.CollectionPaginate(ctx, k.Supply, pagination, func(key string, value math.Int) (sdk.Coin, error) { + return sdk.NewCoin(key, value), nil + }) if err != nil { return nil, nil, err } - coins := sdk.NewCoins() - for _, res := range results { - coins = coins.Add(sdk.NewCoin(res.Key, res.Value)) - } return coins, pageResp, nil } diff --git a/x/circuit/go.mod b/x/circuit/go.mod index 1e3eebabb7e66..60af1396608a6 100644 --- a/x/circuit/go.mod +++ b/x/circuit/go.mod @@ -12,7 +12,7 @@ require ( cosmossdk.io/store v1.0.0-alpha.1 github.com/cockroachdb/errors v1.10.0 github.com/cometbft/cometbft v0.38.0-rc2 - github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713093628-90d9a75d4125 + github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713152238-de8d95cc44b5 github.com/cosmos/gogoproto v1.4.10 github.com/golang/protobuf v1.5.3 github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -24,7 +24,7 @@ require ( require ( cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/x/circuit/go.sum b/x/circuit/go.sum index 6480757a412c4..c5a37a5e13917 100644 --- a/x/circuit/go.sum +++ b/x/circuit/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -168,8 +168,8 @@ github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0 github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713093628-90d9a75d4125 h1:2aGCqfxWf2AAvLOUHaRiByle6n0FPRdeOF/62JTldh0= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713093628-90d9a75d4125/go.mod h1:LME6v5XztqVK7/1uTQj/G6ZJdosJEz24rKaPYk+WbqI= +github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713152238-de8d95cc44b5 h1:6s31oUkdv9/uEuCIQ/eUXxOOhfJ6gAHbX/9C2mollhY= +github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713152238-de8d95cc44b5/go.mod h1:LME6v5XztqVK7/1uTQj/G6ZJdosJEz24rKaPYk+WbqI= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= diff --git a/x/circuit/keeper/query.go b/x/circuit/keeper/query.go index 681a04c210ae8..931fe828d230d 100644 --- a/x/circuit/keeper/query.go +++ b/x/circuit/keeper/query.go @@ -42,26 +42,26 @@ func (qs QueryServer) Account(c context.Context, req *types.QueryAccountRequest) // Account returns account permissions. func (qs QueryServer) Accounts(ctx context.Context, req *types.QueryAccountsRequest) (*types.AccountsResponse, error) { - var accounts []*types.GenesisAccountPermissions - results, pageRes, err := query.CollectionPaginate[[]byte, types.Permissions](ctx, qs.keeper.Permissions, req.Pagination) + results, pageRes, err := query.CollectionPaginate( + ctx, + qs.keeper.Permissions, + req.Pagination, + func(key []byte, value types.Permissions) (*types.GenesisAccountPermissions, error) { + addrStr, err := qs.keeper.addressCodec.BytesToString(key) + if err != nil { + return nil, err + } + return &types.GenesisAccountPermissions{ + Address: addrStr, + Permissions: &value, + }, nil + }, + ) if err != nil { return nil, err } - for _, result := range results { - result := result - address, err := qs.keeper.addressCodec.BytesToString(result.Key) - if err != nil { - return nil, err - } - - accounts = append(accounts, &types.GenesisAccountPermissions{ - Address: address, - Permissions: &result.Value, - }) - } - - return &types.AccountsResponse{Accounts: accounts, Pagination: pageRes}, nil + return &types.AccountsResponse{Accounts: results, Pagination: pageRes}, nil } // DisabledList returns a list of disabled message urls diff --git a/x/evidence/go.mod b/x/evidence/go.mod index 9840b37d96d3e..b7d34fd8863df 100644 --- a/x/evidence/go.mod +++ b/x/evidence/go.mod @@ -13,7 +13,7 @@ require ( cosmossdk.io/store v1.0.0-alpha.1 github.com/cometbft/cometbft v0.38.0-rc2 github.com/cosmos/cosmos-proto v1.0.0-beta.3 - github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713093628-90d9a75d4125 + github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713152238-de8d95cc44b5 github.com/cosmos/gogoproto v1.4.10 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 @@ -26,7 +26,7 @@ require ( ) require ( - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/x/evidence/go.sum b/x/evidence/go.sum index 8cb86d868c289..80d8dd39b2498 100644 --- a/x/evidence/go.sum +++ b/x/evidence/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -175,8 +175,8 @@ github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0 github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713093628-90d9a75d4125 h1:2aGCqfxWf2AAvLOUHaRiByle6n0FPRdeOF/62JTldh0= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713093628-90d9a75d4125/go.mod h1:LME6v5XztqVK7/1uTQj/G6ZJdosJEz24rKaPYk+WbqI= +github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713152238-de8d95cc44b5 h1:6s31oUkdv9/uEuCIQ/eUXxOOhfJ6gAHbX/9C2mollhY= +github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230713152238-de8d95cc44b5/go.mod h1:LME6v5XztqVK7/1uTQj/G6ZJdosJEz24rKaPYk+WbqI= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= diff --git a/x/evidence/keeper/grpc_query.go b/x/evidence/keeper/grpc_query.go index 38ee61c00bd11..22d2be5c24580 100644 --- a/x/evidence/keeper/grpc_query.go +++ b/x/evidence/keeper/grpc_query.go @@ -68,18 +68,12 @@ func (k Querier) AllEvidence(ctx context.Context, req *types.QueryAllEvidenceReq return nil, status.Errorf(codes.InvalidArgument, "empty request") } - var evidence []*codectypes.Any - _, pageRes, err := query.CollectionFilteredPaginate(ctx, k.k.Evidences, req.Pagination, func(_ []byte, value exported.Evidence) (include bool, err error) { - evidenceAny, err := codectypes.NewAnyWithValue(value) - if err != nil { - return false, err - } - evidence = append(evidence, evidenceAny) - return false, nil // we don't include results because we're appending them + evidences, pageRes, err := query.CollectionPaginate(ctx, k.k.Evidences, req.Pagination, func(_ []byte, value exported.Evidence) (*codectypes.Any, error) { + return codectypes.NewAnyWithValue(value) }) if err != nil { return nil, err } - return &types.QueryAllEvidenceResponse{Evidence: evidence, Pagination: pageRes}, nil + return &types.QueryAllEvidenceResponse{Evidence: evidences, Pagination: pageRes}, nil } diff --git a/x/feegrant/go.mod b/x/feegrant/go.mod index d5d5b42569925..11f09d9d8c7aa 100644 --- a/x/feegrant/go.mod +++ b/x/feegrant/go.mod @@ -27,7 +27,7 @@ require ( require ( cosmossdk.io/collections v0.3.0 // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/x/feegrant/go.sum b/x/feegrant/go.sum index ff168d7298611..1a56d2158cf0a 100644 --- a/x/feegrant/go.sum +++ b/x/feegrant/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/x/gov/abci.go b/x/gov/abci.go index 4ed3942463d45..35bb9518ec5a3 100644 --- a/x/gov/abci.go +++ b/x/gov/abci.go @@ -124,6 +124,7 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error { messages, err := proposal.GetMsgs() if err != nil { proposal.Status = v1.StatusFailed + proposal.FailedReason = err.Error() tagValue = types.AttributeValueProposalFailed logMsg = fmt.Sprintf("passed proposal (%v) failed to execute; msgs: %s", proposal, err) @@ -157,6 +158,7 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error { ctx.EventManager().EmitEvents(events) } else { proposal.Status = v1.StatusFailed + proposal.FailedReason = err.Error() tagValue = types.AttributeValueProposalFailed logMsg = fmt.Sprintf("passed, but msg %d (%s) failed on execution: %s", idx, sdk.MsgTypeURL(msg), err) } @@ -182,6 +184,7 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error { logMsg = "expedited proposal converted to regular" default: proposal.Status = v1.StatusRejected + proposal.FailedReason = "proposal did not get enough votes to pass" tagValue = types.AttributeValueProposalRejected logMsg = "rejected" } diff --git a/x/gov/keeper/grpc_query.go b/x/gov/keeper/grpc_query.go index a4b4a035140a1..070be73711cb5 100644 --- a/x/gov/keeper/grpc_query.go +++ b/x/gov/keeper/grpc_query.go @@ -56,8 +56,7 @@ func (q queryServer) Proposal(ctx context.Context, req *v1.QueryProposalRequest) // Proposals implements the Query/Proposals gRPC method func (q queryServer) Proposals(ctx context.Context, req *v1.QueryProposalsRequest) (*v1.QueryProposalsResponse, error) { - var filteredProposals []*v1.Proposal - _, pageRes, err := query.CollectionFilteredPaginate(ctx, q.k.Proposals, req.Pagination, func(key uint64, p v1.Proposal) (bool, error) { + filteredProposals, pageRes, err := query.CollectionFilteredPaginate(ctx, q.k.Proposals, req.Pagination, func(key uint64, p v1.Proposal) (include bool, err error) { matchVoter, matchDepositor, matchStatus := true, true, true // match status (if supplied/valid) @@ -90,11 +89,14 @@ func (q queryServer) Proposals(ctx context.Context, req *v1.QueryProposalsReques // if all match, append to results if matchVoter && matchDepositor && matchStatus { - filteredProposals = append(filteredProposals, &p) + return true, nil } // continue to next item, do not include because we're appending results above. return false, nil + }, func(_ uint64, value v1.Proposal) (*v1.Proposal, error) { + return &value, nil }) + if err != nil && !errors.IsOf(err, collections.ErrInvalidIterator) { return nil, status.Error(codes.Internal, err.Error()) } @@ -142,10 +144,8 @@ func (q queryServer) Votes(ctx context.Context, req *v1.QueryVotesRequest) (*v1. return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") } - var votes v1.Votes - _, pageRes, err := query.CollectionFilteredPaginate(ctx, q.k.Votes, req.Pagination, func(_ collections.Pair[uint64, sdk.AccAddress], value v1.Vote) (include bool, err error) { - votes = append(votes, &value) - return false, nil // not including results because they're being appended. + votes, pageRes, err := query.CollectionPaginate(ctx, q.k.Votes, req.Pagination, func(_ collections.Pair[uint64, sdk.AccAddress], value v1.Vote) (vote *v1.Vote, err error) { + return &value, nil }, query.WithCollectionPaginationPairPrefix[uint64, sdk.AccAddress](req.ProposalId)) if err != nil { return nil, status.Error(codes.Internal, err.Error()) @@ -227,9 +227,8 @@ func (q queryServer) Deposits(ctx context.Context, req *v1.QueryDepositsRequest) } var deposits []*v1.Deposit - _, pageRes, err := query.CollectionFilteredPaginate(ctx, q.k.Deposits, req.Pagination, func(_ collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (bool, error) { - deposits = append(deposits, &deposit) - return false, nil // we don't include results as they're being appended to the slice above. + deposits, pageRes, err := query.CollectionPaginate(ctx, q.k.Deposits, req.Pagination, func(_ collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (*v1.Deposit, error) { + return &deposit, nil }, query.WithCollectionPaginationPairPrefix[uint64, sdk.AccAddress](req.ProposalId)) if err != nil { return nil, status.Error(codes.Internal, err.Error()) diff --git a/x/gov/keeper/grpc_query_test.go b/x/gov/keeper/grpc_query_test.go index 4ed4d5e8cccc9..4edfd04651f9d 100644 --- a/x/gov/keeper/grpc_query_test.go +++ b/x/gov/keeper/grpc_query_test.go @@ -233,7 +233,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryProposals() { true, }, { - "request 2nd page with limit 4", + "request 2nd page with limit 3", func() { req = &v1.QueryProposalsRequest{ Pagination: &query.PageRequest{Offset: 3, Limit: 3}, @@ -307,6 +307,70 @@ func (suite *KeeperTestSuite) TestGRPCQueryProposals() { }, true, }, + { + "request with filter of status voting period", + func() { + req = &v1.QueryProposalsRequest{ + ProposalStatus: v1.StatusVotingPeriod, + } + + var proposals []*v1.Proposal + for i := 0; i < len(testProposals); i++ { + if testProposals[i].GetStatus() == v1.StatusVotingPeriod { + proposals = append(proposals, testProposals[i]) + } + } + + expRes = &v1.QueryProposalsResponse{ + Proposals: proposals, + } + }, + true, + }, + { + "request with filter of status deposit period", + func() { + req = &v1.QueryProposalsRequest{ + ProposalStatus: v1.StatusDepositPeriod, + } + + var proposals []*v1.Proposal + for i := 0; i < len(testProposals); i++ { + if testProposals[i].GetStatus() == v1.StatusDepositPeriod { + proposals = append(proposals, testProposals[i]) + } + } + + expRes = &v1.QueryProposalsResponse{ + Proposals: proposals, + } + }, + true, + }, + { + "request with filter of status deposit period with limit 2", + func() { + req = &v1.QueryProposalsRequest{ + ProposalStatus: v1.StatusDepositPeriod, + Pagination: &query.PageRequest{ + Limit: 2, + CountTotal: true, + }, + } + + var proposals []*v1.Proposal + for i := 0; i < len(testProposals) && len(proposals) < 2; i++ { + if testProposals[i].GetStatus() == v1.StatusDepositPeriod { + proposals = append(proposals, testProposals[i]) + } + } + + expRes = &v1.QueryProposalsResponse{ + Proposals: proposals, + } + }, + true, + }, } for _, testCase := range testCases { diff --git a/x/gov/migrations/v3/json_test.go b/x/gov/migrations/v3/json_test.go index 15d6d6acbd763..a9089cf686269 100644 --- a/x/gov/migrations/v3/json_test.go +++ b/x/gov/migrations/v3/json_test.go @@ -91,6 +91,7 @@ func TestMigrateJSON(t *testing.T) { { "deposit_end_time": "2001-09-09T01:46:40Z", "expedited": false, + "failed_reason": "", "final_tally_result": { "abstain_count": "0", "no_count": "0", diff --git a/x/gov/types/v1/gov.pb.go b/x/gov/types/v1/gov.pb.go index 7d65f395125b3..c4dcc507c9de6 100644 --- a/x/gov/types/v1/gov.pb.go +++ b/x/gov/types/v1/gov.pb.go @@ -282,6 +282,10 @@ type Proposal struct { // // Since: cosmos-sdk 0.50 Expedited bool `protobuf:"varint,14,opt,name=expedited,proto3" json:"expedited,omitempty"` + // failed_reason defines the reason why the proposal failed + // + // Since: cosmos-sdk 0.50 + FailedReason string `protobuf:"bytes,15,opt,name=failed_reason,json=failedReason,proto3" json:"failed_reason,omitempty"` } func (m *Proposal) Reset() { *m = Proposal{} } @@ -415,6 +419,13 @@ func (m *Proposal) GetExpedited() bool { return false } +func (m *Proposal) GetFailedReason() string { + if m != nil { + return m.FailedReason + } + return "" +} + // TallyResult defines a standard tally for a governance proposal. type TallyResult struct { // yes_count is the number of yes votes on a proposal. @@ -940,94 +951,96 @@ func init() { func init() { proto.RegisterFile("cosmos/gov/v1/gov.proto", fileDescriptor_e05cb1c0d030febb) } var fileDescriptor_e05cb1c0d030febb = []byte{ - // 1389 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcb, 0x6e, 0xdb, 0x46, - 0x17, 0x36, 0x75, 0xd7, 0xd1, 0xc5, 0xca, 0xd8, 0x89, 0x69, 0x27, 0x96, 0x1c, 0x21, 0x08, 0xfc, - 0xe7, 0x22, 0xfd, 0x4e, 0x9a, 0x2e, 0x9a, 0x02, 0x85, 0x64, 0x31, 0x0d, 0x8d, 0xc4, 0x52, 0x29, - 0x45, 0x4e, 0xba, 0x21, 0x28, 0x71, 0x22, 0x13, 0x15, 0x39, 0x2a, 0x39, 0x52, 0xac, 0x47, 0xe8, - 0x2e, 0xcb, 0xae, 0x8a, 0x2e, 0xbb, 0xec, 0x22, 0xe8, 0x33, 0x64, 0x55, 0x04, 0xe9, 0xa2, 0xdd, - 0x34, 0x29, 0x92, 0x45, 0x81, 0x3c, 0x45, 0xc1, 0xe1, 0x50, 0x94, 0x64, 0xb5, 0xb6, 0xb3, 0xb1, - 0xc5, 0x73, 0xbe, 0xef, 0x9b, 0x33, 0xe7, 0x32, 0x43, 0xc2, 0x5a, 0x97, 0x38, 0x26, 0x71, 0xca, - 0x3d, 0x32, 0x2a, 0x8f, 0x76, 0xdc, 0x7f, 0xa5, 0x81, 0x4d, 0x28, 0x41, 0x19, 0xcf, 0x51, 0x72, - 0x2d, 0xa3, 0x9d, 0x8d, 0x3c, 0xc7, 0x75, 0x34, 0x07, 0x97, 0x47, 0x3b, 0x1d, 0x4c, 0xb5, 0x9d, - 0x72, 0x97, 0x18, 0x96, 0x07, 0xdf, 0x58, 0xed, 0x91, 0x1e, 0x61, 0x3f, 0xcb, 0xee, 0x2f, 0x6e, - 0x2d, 0xf4, 0x08, 0xe9, 0xf5, 0x71, 0x99, 0x3d, 0x75, 0x86, 0x4f, 0xcb, 0xd4, 0x30, 0xb1, 0x43, - 0x35, 0x73, 0xc0, 0x01, 0xeb, 0xf3, 0x00, 0xcd, 0x1a, 0x73, 0x57, 0x7e, 0xde, 0xa5, 0x0f, 0x6d, - 0x8d, 0x1a, 0xc4, 0x5f, 0x71, 0xdd, 0x8b, 0x48, 0xf5, 0x16, 0xe5, 0xd1, 0x7a, 0xae, 0x73, 0x9a, - 0x69, 0x58, 0xa4, 0xcc, 0xfe, 0x7a, 0xa6, 0x22, 0x01, 0x74, 0x80, 0x8d, 0xde, 0x21, 0xc5, 0x7a, - 0x9b, 0x50, 0x5c, 0x1f, 0xb8, 0x4a, 0x68, 0x07, 0x62, 0x84, 0xfd, 0x12, 0x85, 0x2d, 0x61, 0x3b, - 0x7b, 0x6b, 0xbd, 0x34, 0xb3, 0xeb, 0x52, 0x00, 0x55, 0x38, 0x10, 0x5d, 0x85, 0xd8, 0x33, 0x26, - 0x24, 0x86, 0xb6, 0x84, 0xed, 0x64, 0x35, 0xfb, 0xfa, 0xc5, 0x4d, 0xe0, 0xac, 0x1a, 0xee, 0x2a, - 0xdc, 0x5b, 0xfc, 0x51, 0x80, 0x78, 0x0d, 0x0f, 0x88, 0x63, 0x50, 0x54, 0x80, 0xd4, 0xc0, 0x26, - 0x03, 0xe2, 0x68, 0x7d, 0xd5, 0xd0, 0xd9, 0x5a, 0x11, 0x05, 0x7c, 0x93, 0xac, 0xa3, 0x4f, 0x21, - 0xa9, 0x7b, 0x58, 0x62, 0x73, 0x5d, 0xf1, 0xf5, 0x8b, 0x9b, 0xab, 0x5c, 0xb7, 0xa2, 0xeb, 0x36, - 0x76, 0x9c, 0x26, 0xb5, 0x0d, 0xab, 0xa7, 0x04, 0x50, 0xf4, 0x39, 0xc4, 0x34, 0x93, 0x0c, 0x2d, - 0x2a, 0x86, 0xb7, 0xc2, 0xdb, 0xa9, 0x20, 0x7e, 0xb7, 0x4c, 0x25, 0x5e, 0xa6, 0xd2, 0x2e, 0x31, - 0xac, 0x6a, 0xf2, 0xe5, 0x9b, 0xc2, 0xd2, 0x4f, 0x7f, 0xff, 0x7c, 0x4d, 0x50, 0x38, 0xa7, 0xf8, - 0x36, 0x0a, 0x89, 0x06, 0x0f, 0x02, 0x65, 0x21, 0x34, 0x09, 0x2d, 0x64, 0xe8, 0xe8, 0xff, 0x90, - 0x30, 0xb1, 0xe3, 0x68, 0x3d, 0xec, 0x88, 0x21, 0x26, 0xbe, 0x5a, 0xf2, 0x2a, 0x52, 0xf2, 0x2b, - 0x52, 0xaa, 0x58, 0x63, 0x65, 0x82, 0x42, 0x77, 0x20, 0xe6, 0x50, 0x8d, 0x0e, 0x1d, 0x31, 0xcc, - 0x92, 0xb9, 0x39, 0x97, 0x4c, 0x7f, 0xa9, 0x26, 0x03, 0x29, 0x1c, 0x8c, 0xee, 0x03, 0x7a, 0x6a, - 0x58, 0x5a, 0x5f, 0xa5, 0x5a, 0xbf, 0x3f, 0x56, 0x6d, 0xec, 0x0c, 0xfb, 0x54, 0x8c, 0x6c, 0x09, - 0xdb, 0xa9, 0x5b, 0x1b, 0x73, 0x12, 0x2d, 0x17, 0xa2, 0x30, 0x84, 0x92, 0x63, 0xac, 0x29, 0x0b, - 0xaa, 0x40, 0xca, 0x19, 0x76, 0x4c, 0x83, 0xaa, 0x6e, 0x9b, 0x89, 0x51, 0x2e, 0x31, 0x1f, 0x75, - 0xcb, 0xef, 0xc1, 0x6a, 0xe4, 0xf9, 0xdb, 0x82, 0xa0, 0x80, 0x47, 0x72, 0xcd, 0x68, 0x0f, 0x72, - 0x3c, 0xbb, 0x2a, 0xb6, 0x74, 0x4f, 0x27, 0x76, 0x4a, 0x9d, 0x2c, 0x67, 0x4a, 0x96, 0xce, 0xb4, - 0x64, 0xc8, 0x50, 0x42, 0xb5, 0xbe, 0xca, 0xed, 0x62, 0xfc, 0x0c, 0x35, 0x4a, 0x33, 0xaa, 0xdf, - 0x40, 0x0f, 0xe0, 0xdc, 0x88, 0x50, 0xc3, 0xea, 0xa9, 0x0e, 0xd5, 0x6c, 0xbe, 0xbf, 0xc4, 0x29, - 0xe3, 0x5a, 0xf6, 0xa8, 0x4d, 0x97, 0xc9, 0x02, 0xbb, 0x0f, 0xdc, 0x14, 0xec, 0x31, 0x79, 0x4a, - 0xad, 0x8c, 0x47, 0xf4, 0xb7, 0xb8, 0xe1, 0x36, 0x09, 0xd5, 0x74, 0x8d, 0x6a, 0x22, 0xb8, 0x6d, - 0xab, 0x4c, 0x9e, 0xd1, 0x2a, 0x44, 0xa9, 0x41, 0xfb, 0x58, 0x4c, 0x31, 0x87, 0xf7, 0x80, 0x44, - 0x88, 0x3b, 0x43, 0xd3, 0xd4, 0xec, 0xb1, 0x98, 0x66, 0x76, 0xff, 0x11, 0x7d, 0x02, 0x09, 0x6f, - 0x22, 0xb0, 0x2d, 0x66, 0x4e, 0x18, 0x81, 0x09, 0x12, 0x5d, 0x82, 0x24, 0x3e, 0x1a, 0x60, 0xdd, - 0xa0, 0x58, 0x17, 0xb3, 0x5b, 0xc2, 0x76, 0x42, 0x09, 0x0c, 0xc5, 0xdf, 0x05, 0x48, 0x4d, 0x77, - 0xc8, 0x75, 0x48, 0x8e, 0xb1, 0xa3, 0x76, 0xd9, 0xc8, 0x08, 0xc7, 0xe6, 0x57, 0xb6, 0xa8, 0x92, - 0x18, 0x63, 0x67, 0xd7, 0xf5, 0xa3, 0xdb, 0x90, 0xd1, 0x3a, 0x0e, 0xd5, 0x0c, 0x8b, 0x13, 0x42, - 0x0b, 0x09, 0x69, 0x0e, 0xf2, 0x48, 0xff, 0x83, 0x84, 0x45, 0x38, 0x3e, 0xbc, 0x10, 0x1f, 0xb7, - 0x88, 0x07, 0xbd, 0x0b, 0xc8, 0x22, 0xea, 0x33, 0x83, 0x1e, 0xaa, 0x23, 0x4c, 0x7d, 0x52, 0x64, - 0x21, 0x69, 0xd9, 0x22, 0x07, 0x06, 0x3d, 0x6c, 0x63, 0xea, 0x91, 0x8b, 0xbf, 0x08, 0x10, 0x71, - 0x4f, 0xa7, 0x93, 0xcf, 0x96, 0x12, 0x44, 0x47, 0x84, 0xe2, 0x93, 0xcf, 0x15, 0x0f, 0x86, 0xee, - 0x42, 0xdc, 0x3b, 0xea, 0x1c, 0x31, 0xc2, 0x1a, 0xf6, 0xf2, 0xdc, 0x10, 0x1e, 0x3f, 0x47, 0x15, - 0x9f, 0x31, 0xd3, 0x10, 0xd1, 0xd9, 0x86, 0xd8, 0x8b, 0x24, 0xc2, 0xb9, 0x48, 0xf1, 0x4f, 0x01, - 0x32, 0xbc, 0xad, 0x1b, 0x9a, 0xad, 0x99, 0x0e, 0x7a, 0x02, 0x29, 0xd3, 0xb0, 0x26, 0x53, 0x22, - 0x9c, 0x34, 0x25, 0x9b, 0xee, 0x94, 0x7c, 0x78, 0x53, 0x38, 0x3f, 0xc5, 0xba, 0x41, 0x4c, 0x83, - 0x62, 0x73, 0x40, 0xc7, 0x0a, 0x98, 0x86, 0xe5, 0xcf, 0x8d, 0x09, 0xc8, 0xd4, 0x8e, 0x7c, 0x90, - 0x3a, 0xc0, 0xb6, 0x41, 0x74, 0x96, 0x08, 0x77, 0x85, 0xf9, 0x66, 0xaf, 0xf1, 0x0b, 0xa6, 0x7a, - 0xe5, 0xc3, 0x9b, 0xc2, 0xa5, 0xe3, 0xc4, 0x60, 0x91, 0xef, 0xdd, 0x59, 0xc8, 0x99, 0xda, 0x91, - 0xbf, 0x13, 0xe6, 0xff, 0x2c, 0x24, 0x0a, 0xc5, 0xc7, 0x90, 0x6e, 0xb3, 0x19, 0xe1, 0xbb, 0xab, - 0x01, 0x9f, 0x19, 0x7f, 0x75, 0xe1, 0xa4, 0xd5, 0x23, 0x4c, 0x3d, 0xed, 0xb1, 0xa6, 0x94, 0x7f, - 0xf0, 0x9b, 0x99, 0x2b, 0x5f, 0x85, 0xd8, 0xb7, 0x43, 0x62, 0x0f, 0xcd, 0x05, 0x9d, 0xcc, 0x6e, - 0x22, 0xcf, 0x8b, 0x6e, 0x40, 0x92, 0x1e, 0xda, 0xd8, 0x39, 0x24, 0x7d, 0xfd, 0x5f, 0x2e, 0xad, - 0x00, 0x80, 0xee, 0x40, 0x96, 0x75, 0x63, 0x40, 0x09, 0x2f, 0xa4, 0x64, 0x5c, 0x54, 0xcb, 0x07, - 0xb1, 0x00, 0x7f, 0x8b, 0x43, 0x8c, 0xc7, 0x26, 0x9d, 0xb1, 0xa6, 0x53, 0x27, 0xdf, 0x74, 0xfd, - 0x1e, 0x7e, 0x5c, 0xfd, 0x22, 0x8b, 0xeb, 0x73, 0xbc, 0x16, 0xe1, 0x8f, 0xa8, 0xc5, 0x54, 0xde, - 0x23, 0xa7, 0xcf, 0x7b, 0xf4, 0xec, 0x79, 0x8f, 0x9d, 0x22, 0xef, 0x48, 0x86, 0x75, 0x37, 0xd1, - 0x86, 0x65, 0x50, 0x23, 0xb8, 0x6a, 0x54, 0x16, 0xbe, 0x18, 0x5f, 0xa8, 0x70, 0xc1, 0x34, 0x2c, - 0xd9, 0xc3, 0xf3, 0xf4, 0x28, 0x2e, 0x1a, 0x55, 0xe1, 0xfc, 0xe4, 0x24, 0xe9, 0x6a, 0x56, 0x17, - 0xf7, 0xb9, 0x4c, 0x62, 0xa1, 0xcc, 0x8a, 0x0f, 0xde, 0x65, 0x58, 0x4f, 0x63, 0x0f, 0x56, 0xe7, - 0x35, 0x74, 0xec, 0x50, 0x76, 0xbf, 0xfc, 0xd7, 0xd9, 0x83, 0x66, 0xc5, 0x6a, 0xd8, 0xa1, 0xe8, - 0x00, 0xd6, 0x26, 0x27, 0xb9, 0x3a, 0x5b, 0x37, 0x38, 0x5d, 0xdd, 0xce, 0x4f, 0xf8, 0xed, 0xe9, - 0x02, 0x7e, 0x01, 0x2b, 0x81, 0x70, 0x90, 0xef, 0xd4, 0xc2, 0x6d, 0xa2, 0x09, 0x34, 0x48, 0xfa, - 0x63, 0x08, 0x94, 0xd5, 0xe9, 0x3e, 0x4f, 0x9f, 0xa1, 0xcf, 0x83, 0x18, 0x1e, 0x06, 0x0d, 0xbf, - 0x0d, 0xb9, 0xce, 0xd0, 0xb6, 0xdc, 0xed, 0x62, 0x95, 0x77, 0x59, 0x86, 0xdd, 0x6a, 0x59, 0xd7, - 0xee, 0x1e, 0xb9, 0x5f, 0x79, 0xdd, 0x55, 0x81, 0x4d, 0x86, 0x9c, 0xa4, 0x7b, 0x32, 0x24, 0x36, - 0x76, 0xd9, 0xfc, 0x32, 0xdc, 0x70, 0x41, 0xfe, 0x9b, 0x97, 0x3f, 0x0d, 0x1e, 0x02, 0x5d, 0x81, - 0x6c, 0xb0, 0x98, 0xdb, 0x56, 0xe2, 0x32, 0xe3, 0xa4, 0xfd, 0xa5, 0xdc, 0xeb, 0xe6, 0xda, 0x77, - 0x02, 0xc0, 0xd4, 0x2b, 0xf3, 0x45, 0x58, 0x6b, 0xd7, 0x5b, 0x92, 0x5a, 0x6f, 0xb4, 0xe4, 0xfa, - 0xbe, 0xfa, 0x68, 0xbf, 0xd9, 0x90, 0x76, 0xe5, 0x7b, 0xb2, 0x54, 0xcb, 0x2d, 0xa1, 0x15, 0x58, - 0x9e, 0x76, 0x3e, 0x91, 0x9a, 0x39, 0x01, 0xad, 0xc1, 0xca, 0xb4, 0xb1, 0x52, 0x6d, 0xb6, 0x2a, - 0xf2, 0x7e, 0x2e, 0x84, 0x10, 0x64, 0xa7, 0x1d, 0xfb, 0xf5, 0x5c, 0x18, 0x5d, 0x02, 0x71, 0xd6, - 0xa6, 0x1e, 0xc8, 0xad, 0xfb, 0x6a, 0x5b, 0x6a, 0xd5, 0x73, 0x91, 0x6b, 0xbf, 0x0a, 0x90, 0x9d, - 0x7d, 0x8d, 0x44, 0x05, 0xb8, 0xd8, 0x50, 0xea, 0x8d, 0x7a, 0xb3, 0xf2, 0x40, 0x6d, 0xb6, 0x2a, - 0xad, 0x47, 0xcd, 0xb9, 0x98, 0x8a, 0x90, 0x9f, 0x07, 0xd4, 0xa4, 0x46, 0xbd, 0x29, 0xb7, 0xd4, - 0x86, 0xa4, 0xc8, 0xf5, 0x5a, 0x4e, 0x40, 0x97, 0x61, 0x73, 0x1e, 0xd3, 0xae, 0xb7, 0xe4, 0xfd, - 0x2f, 0x7d, 0x48, 0x08, 0x6d, 0xc0, 0x85, 0x79, 0x48, 0xa3, 0xd2, 0x6c, 0x4a, 0x35, 0x2f, 0xe8, - 0x79, 0x9f, 0x22, 0xed, 0x49, 0xbb, 0x2d, 0xa9, 0x96, 0x8b, 0x2c, 0x62, 0xde, 0xab, 0xc8, 0x0f, - 0xa4, 0x5a, 0x2e, 0x5a, 0x95, 0x5e, 0xbe, 0xcb, 0x0b, 0xaf, 0xde, 0xe5, 0x85, 0xbf, 0xde, 0xe5, - 0x85, 0xe7, 0xef, 0xf3, 0x4b, 0xaf, 0xde, 0xe7, 0x97, 0xfe, 0x78, 0x9f, 0x5f, 0xfa, 0xfa, 0x7a, - 0xcf, 0xa0, 0x87, 0xc3, 0x4e, 0xa9, 0x4b, 0x4c, 0xfe, 0x71, 0xc3, 0xff, 0xdd, 0x74, 0xf4, 0x6f, - 0xca, 0x47, 0xec, 0x83, 0x8d, 0x8e, 0x07, 0xd8, 0x71, 0xbf, 0xc6, 0x62, 0x6c, 0x02, 0x6e, 0xff, - 0x13, 0x00, 0x00, 0xff, 0xff, 0xba, 0xe0, 0x97, 0xe3, 0xce, 0x0d, 0x00, 0x00, + // 1415 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4b, 0x6f, 0xdb, 0xc6, + 0x16, 0x36, 0x25, 0x59, 0x96, 0x8f, 0x1e, 0x56, 0xc6, 0x4e, 0x4c, 0x3b, 0xb1, 0xec, 0xe8, 0x06, + 0x81, 0x6f, 0x1e, 0xd2, 0x75, 0x72, 0xd3, 0x45, 0x53, 0xa0, 0x90, 0x2d, 0xa6, 0xa1, 0x91, 0x58, + 0x2a, 0xa5, 0xd8, 0x49, 0x37, 0x04, 0x6d, 0x4e, 0xe4, 0x41, 0x45, 0x8e, 0xca, 0x19, 0x29, 0xd6, + 0xbe, 0x9b, 0xee, 0xb2, 0xec, 0xaa, 0xe8, 0xb2, 0xcb, 0x2e, 0x82, 0xfe, 0x86, 0xac, 0x8a, 0x20, + 0x5d, 0xb4, 0x9b, 0xa6, 0x45, 0xb2, 0x28, 0x90, 0x5f, 0x51, 0x70, 0x38, 0x14, 0x25, 0x59, 0xad, + 0xed, 0x6c, 0x6c, 0xf1, 0x9c, 0xef, 0xfb, 0xe6, 0xcc, 0x79, 0xcc, 0x90, 0xb0, 0x78, 0x40, 0x99, + 0x43, 0x59, 0xb9, 0x45, 0x7b, 0xe5, 0xde, 0x86, 0xff, 0xaf, 0xd4, 0xf1, 0x28, 0xa7, 0x28, 0x1b, + 0x38, 0x4a, 0xbe, 0xa5, 0xb7, 0xb1, 0x5c, 0x90, 0xb8, 0x7d, 0x8b, 0xe1, 0x72, 0x6f, 0x63, 0x1f, + 0x73, 0x6b, 0xa3, 0x7c, 0x40, 0x89, 0x1b, 0xc0, 0x97, 0x17, 0x5a, 0xb4, 0x45, 0xc5, 0xcf, 0xb2, + 0xff, 0x4b, 0x5a, 0x57, 0x5b, 0x94, 0xb6, 0xda, 0xb8, 0x2c, 0x9e, 0xf6, 0xbb, 0x4f, 0xcb, 0x9c, + 0x38, 0x98, 0x71, 0xcb, 0xe9, 0x48, 0xc0, 0xd2, 0x38, 0xc0, 0x72, 0xfb, 0xd2, 0x55, 0x18, 0x77, + 0xd9, 0x5d, 0xcf, 0xe2, 0x84, 0x86, 0x2b, 0x2e, 0x05, 0x11, 0x99, 0xc1, 0xa2, 0x32, 0xda, 0xc0, + 0x75, 0xce, 0x72, 0x88, 0x4b, 0xcb, 0xe2, 0x6f, 0x60, 0x2a, 0x52, 0x40, 0x7b, 0x98, 0xb4, 0x0e, + 0x39, 0xb6, 0x77, 0x29, 0xc7, 0xb5, 0x8e, 0xaf, 0x84, 0x36, 0x20, 0x49, 0xc5, 0x2f, 0x55, 0x59, + 0x53, 0xd6, 0x73, 0xb7, 0x96, 0x4a, 0x23, 0xbb, 0x2e, 0x45, 0x50, 0x43, 0x02, 0xd1, 0x55, 0x48, + 0x3e, 0x13, 0x42, 0x6a, 0x6c, 0x4d, 0x59, 0x9f, 0xdd, 0xcc, 0xbd, 0x7e, 0x71, 0x13, 0x24, 0xab, + 0x8a, 0x0f, 0x0c, 0xe9, 0x2d, 0x7e, 0xaf, 0xc0, 0x4c, 0x15, 0x77, 0x28, 0x23, 0x1c, 0xad, 0x42, + 0xba, 0xe3, 0xd1, 0x0e, 0x65, 0x56, 0xdb, 0x24, 0xb6, 0x58, 0x2b, 0x61, 0x40, 0x68, 0xd2, 0x6d, + 0xf4, 0x11, 0xcc, 0xda, 0x01, 0x96, 0x7a, 0x52, 0x57, 0x7d, 0xfd, 0xe2, 0xe6, 0x82, 0xd4, 0xad, + 0xd8, 0xb6, 0x87, 0x19, 0x6b, 0x70, 0x8f, 0xb8, 0x2d, 0x23, 0x82, 0xa2, 0x4f, 0x20, 0x69, 0x39, + 0xb4, 0xeb, 0x72, 0x35, 0xbe, 0x16, 0x5f, 0x4f, 0x47, 0xf1, 0xfb, 0x65, 0x2a, 0xc9, 0x32, 0x95, + 0xb6, 0x28, 0x71, 0x37, 0x67, 0x5f, 0xbe, 0x59, 0x9d, 0xfa, 0xe1, 0xaf, 0x1f, 0xaf, 0x29, 0x86, + 0xe4, 0x14, 0xbf, 0x4e, 0x42, 0xaa, 0x2e, 0x83, 0x40, 0x39, 0x88, 0x0d, 0x42, 0x8b, 0x11, 0x1b, + 0xfd, 0x0f, 0x52, 0x0e, 0x66, 0xcc, 0x6a, 0x61, 0xa6, 0xc6, 0x84, 0xf8, 0x42, 0x29, 0xa8, 0x48, + 0x29, 0xac, 0x48, 0xa9, 0xe2, 0xf6, 0x8d, 0x01, 0x0a, 0xdd, 0x81, 0x24, 0xe3, 0x16, 0xef, 0x32, + 0x35, 0x2e, 0x92, 0xb9, 0x32, 0x96, 0xcc, 0x70, 0xa9, 0x86, 0x00, 0x19, 0x12, 0x8c, 0xee, 0x03, + 0x7a, 0x4a, 0x5c, 0xab, 0x6d, 0x72, 0xab, 0xdd, 0xee, 0x9b, 0x1e, 0x66, 0xdd, 0x36, 0x57, 0x13, + 0x6b, 0xca, 0x7a, 0xfa, 0xd6, 0xf2, 0x98, 0x44, 0xd3, 0x87, 0x18, 0x02, 0x61, 0xe4, 0x05, 0x6b, + 0xc8, 0x82, 0x2a, 0x90, 0x66, 0xdd, 0x7d, 0x87, 0x70, 0xd3, 0x6f, 0x33, 0x75, 0x5a, 0x4a, 0x8c, + 0x47, 0xdd, 0x0c, 0x7b, 0x70, 0x33, 0xf1, 0xfc, 0x8f, 0x55, 0xc5, 0x80, 0x80, 0xe4, 0x9b, 0xd1, + 0x36, 0xe4, 0x65, 0x76, 0x4d, 0xec, 0xda, 0x81, 0x4e, 0xf2, 0x94, 0x3a, 0x39, 0xc9, 0xd4, 0x5c, + 0x5b, 0x68, 0xe9, 0x90, 0xe5, 0x94, 0x5b, 0x6d, 0x53, 0xda, 0xd5, 0x99, 0x33, 0xd4, 0x28, 0x23, + 0xa8, 0x61, 0x03, 0x3d, 0x80, 0x73, 0x3d, 0xca, 0x89, 0xdb, 0x32, 0x19, 0xb7, 0x3c, 0xb9, 0xbf, + 0xd4, 0x29, 0xe3, 0x9a, 0x0b, 0xa8, 0x0d, 0x9f, 0x29, 0x02, 0xbb, 0x0f, 0xd2, 0x14, 0xed, 0x71, + 0xf6, 0x94, 0x5a, 0xd9, 0x80, 0x18, 0x6e, 0x71, 0xd9, 0x6f, 0x12, 0x6e, 0xd9, 0x16, 0xb7, 0x54, + 0xf0, 0xdb, 0xd6, 0x18, 0x3c, 0xa3, 0x05, 0x98, 0xe6, 0x84, 0xb7, 0xb1, 0x9a, 0x16, 0x8e, 0xe0, + 0x01, 0xa9, 0x30, 0xc3, 0xba, 0x8e, 0x63, 0x79, 0x7d, 0x35, 0x23, 0xec, 0xe1, 0x23, 0xfa, 0x3f, + 0xa4, 0x82, 0x89, 0xc0, 0x9e, 0x9a, 0x3d, 0x61, 0x04, 0x06, 0x48, 0x74, 0x09, 0x66, 0xf1, 0x51, + 0x07, 0xdb, 0x84, 0x63, 0x5b, 0xcd, 0xad, 0x29, 0xeb, 0x29, 0x23, 0x32, 0xa0, 0xff, 0x40, 0xf6, + 0xa9, 0x45, 0xda, 0xd8, 0x36, 0x3d, 0x6c, 0x31, 0xea, 0xaa, 0x73, 0x62, 0xcd, 0x4c, 0x60, 0x34, + 0x84, 0xad, 0xf8, 0xab, 0x02, 0xe9, 0xe1, 0x36, 0xba, 0x0e, 0xb3, 0x7d, 0xcc, 0xcc, 0x03, 0x31, + 0x57, 0xca, 0xb1, 0x21, 0xd7, 0x5d, 0x6e, 0xa4, 0xfa, 0x98, 0x6d, 0xf9, 0x7e, 0x74, 0x1b, 0xb2, + 0xd6, 0x3e, 0xe3, 0x16, 0x71, 0x25, 0x21, 0x36, 0x91, 0x90, 0x91, 0xa0, 0x80, 0xf4, 0x5f, 0x48, + 0xb9, 0x54, 0xe2, 0xe3, 0x13, 0xf1, 0x33, 0x2e, 0x0d, 0xa0, 0x77, 0x01, 0xb9, 0xd4, 0x7c, 0x46, + 0xf8, 0xa1, 0xd9, 0xc3, 0x3c, 0x24, 0x25, 0x26, 0x92, 0xe6, 0x5c, 0xba, 0x47, 0xf8, 0xe1, 0x2e, + 0xe6, 0x01, 0xb9, 0xf8, 0x93, 0x02, 0x09, 0xff, 0x08, 0x3b, 0xf9, 0x00, 0x2a, 0xc1, 0x74, 0x8f, + 0x72, 0x7c, 0xf2, 0xe1, 0x13, 0xc0, 0xd0, 0x5d, 0x98, 0x09, 0xce, 0x43, 0xa6, 0x26, 0x44, 0x57, + 0x5f, 0x1e, 0x9b, 0xd4, 0xe3, 0x87, 0xad, 0x11, 0x32, 0x46, 0xba, 0x66, 0x7a, 0xb4, 0x6b, 0xb6, + 0x13, 0xa9, 0x78, 0x3e, 0x51, 0xfc, 0x5d, 0x81, 0xac, 0xec, 0xfd, 0xba, 0xe5, 0x59, 0x0e, 0x43, + 0x4f, 0x20, 0xed, 0x10, 0x77, 0x30, 0x4a, 0xca, 0x49, 0xa3, 0xb4, 0xe2, 0x8f, 0xd2, 0xfb, 0x37, + 0xab, 0xe7, 0x87, 0x58, 0x37, 0xa8, 0x43, 0x38, 0x76, 0x3a, 0xbc, 0x6f, 0x80, 0x43, 0xdc, 0x70, + 0xb8, 0x1c, 0x40, 0x8e, 0x75, 0x14, 0x82, 0xcc, 0x0e, 0xf6, 0x08, 0xb5, 0x45, 0x22, 0xfc, 0x15, + 0xc6, 0x27, 0xa2, 0x2a, 0x6f, 0xa1, 0xcd, 0x2b, 0xef, 0xdf, 0xac, 0x5e, 0x3a, 0x4e, 0x8c, 0x16, + 0xf9, 0xd6, 0x1f, 0x98, 0xbc, 0x63, 0x1d, 0x85, 0x3b, 0x11, 0xfe, 0x8f, 0x63, 0xaa, 0x52, 0x7c, + 0x0c, 0x99, 0x5d, 0x31, 0x48, 0x72, 0x77, 0x55, 0x90, 0x83, 0x15, 0xae, 0xae, 0x9c, 0xb4, 0x7a, + 0x42, 0xa8, 0x67, 0x02, 0xd6, 0x90, 0xf2, 0x77, 0x61, 0x33, 0x4b, 0xe5, 0xab, 0x90, 0xfc, 0xaa, + 0x4b, 0xbd, 0xae, 0x33, 0xa1, 0x93, 0xc5, 0x75, 0x15, 0x78, 0xd1, 0x0d, 0x98, 0xe5, 0x87, 0x1e, + 0x66, 0x87, 0xb4, 0x6d, 0xff, 0xc3, 0xcd, 0x16, 0x01, 0xd0, 0x1d, 0xc8, 0x89, 0x6e, 0x8c, 0x28, + 0xf1, 0x89, 0x94, 0xac, 0x8f, 0x6a, 0x86, 0x20, 0x11, 0xe0, 0x2f, 0x33, 0x90, 0x94, 0xb1, 0x69, + 0x67, 0xac, 0xe9, 0xd0, 0xf1, 0x38, 0x5c, 0xbf, 0x87, 0x1f, 0x56, 0xbf, 0xc4, 0xe4, 0xfa, 0x1c, + 0xaf, 0x45, 0xfc, 0x03, 0x6a, 0x31, 0x94, 0xf7, 0xc4, 0xe9, 0xf3, 0x3e, 0x7d, 0xf6, 0xbc, 0x27, + 0x4f, 0x91, 0x77, 0xa4, 0xc3, 0x92, 0x9f, 0x68, 0xe2, 0x12, 0x4e, 0xa2, 0xfb, 0xc8, 0x14, 0xe1, + 0xab, 0x33, 0x13, 0x15, 0x2e, 0x38, 0xc4, 0xd5, 0x03, 0xbc, 0x4c, 0x8f, 0xe1, 0xa3, 0xd1, 0x26, + 0x9c, 0x1f, 0x9c, 0x24, 0x07, 0x96, 0x7b, 0x80, 0xdb, 0x52, 0x26, 0x35, 0x51, 0x66, 0x3e, 0x04, + 0x6f, 0x09, 0x6c, 0xa0, 0xb1, 0x0d, 0x0b, 0xe3, 0x1a, 0x36, 0x66, 0x5c, 0x5c, 0x42, 0xff, 0x76, + 0xf6, 0xa0, 0x51, 0xb1, 0x2a, 0x66, 0x1c, 0xed, 0xc1, 0xe2, 0xe0, 0xb8, 0x37, 0x47, 0xeb, 0x06, + 0xa7, 0xab, 0xdb, 0xf9, 0x01, 0x7f, 0x77, 0xb8, 0x80, 0x9f, 0xc2, 0x7c, 0x24, 0x1c, 0xe5, 0x3b, + 0x3d, 0x71, 0x9b, 0x68, 0x00, 0x8d, 0x92, 0xfe, 0x18, 0x22, 0x65, 0x73, 0xb8, 0xcf, 0x33, 0x67, + 0xe8, 0xf3, 0x28, 0x86, 0x87, 0x51, 0xc3, 0xaf, 0x43, 0x7e, 0xbf, 0xeb, 0xb9, 0xfe, 0x76, 0xb1, + 0x29, 0xbb, 0x2c, 0x2b, 0xae, 0xbe, 0x9c, 0x6f, 0xf7, 0x8f, 0xdc, 0xcf, 0x83, 0xee, 0xaa, 0xc0, + 0x8a, 0x40, 0x0e, 0xd2, 0x3d, 0x18, 0x12, 0x0f, 0xfb, 0x6c, 0x79, 0x63, 0x2e, 0xfb, 0xa0, 0xf0, + 0xf5, 0x2c, 0x9c, 0x86, 0x00, 0x81, 0xae, 0x40, 0x2e, 0x5a, 0xcc, 0x6f, 0x2b, 0x71, 0x87, 0xa6, + 0x8c, 0x4c, 0xb8, 0x94, 0x7f, 0xdd, 0x5c, 0xfb, 0x46, 0x01, 0x18, 0x7a, 0xaf, 0xbe, 0x08, 0x8b, + 0xbb, 0xb5, 0xa6, 0x66, 0xd6, 0xea, 0x4d, 0xbd, 0xb6, 0x63, 0x3e, 0xda, 0x69, 0xd4, 0xb5, 0x2d, + 0xfd, 0x9e, 0xae, 0x55, 0xf3, 0x53, 0x68, 0x1e, 0xe6, 0x86, 0x9d, 0x4f, 0xb4, 0x46, 0x5e, 0x41, + 0x8b, 0x30, 0x3f, 0x6c, 0xac, 0x6c, 0x36, 0x9a, 0x15, 0x7d, 0x27, 0x1f, 0x43, 0x08, 0x72, 0xc3, + 0x8e, 0x9d, 0x5a, 0x3e, 0x8e, 0x2e, 0x81, 0x3a, 0x6a, 0x33, 0xf7, 0xf4, 0xe6, 0x7d, 0x73, 0x57, + 0x6b, 0xd6, 0xf2, 0x89, 0x6b, 0x3f, 0x2b, 0x90, 0x1b, 0x7d, 0xd7, 0x44, 0xab, 0x70, 0xb1, 0x6e, + 0xd4, 0xea, 0xb5, 0x46, 0xe5, 0x81, 0xd9, 0x68, 0x56, 0x9a, 0x8f, 0x1a, 0x63, 0x31, 0x15, 0xa1, + 0x30, 0x0e, 0xa8, 0x6a, 0xf5, 0x5a, 0x43, 0x6f, 0x9a, 0x75, 0xcd, 0xd0, 0x6b, 0xd5, 0xbc, 0x82, + 0x2e, 0xc3, 0xca, 0x38, 0x66, 0xb7, 0xd6, 0xd4, 0x77, 0x3e, 0x0b, 0x21, 0x31, 0xb4, 0x0c, 0x17, + 0xc6, 0x21, 0xf5, 0x4a, 0xa3, 0xa1, 0x55, 0x83, 0xa0, 0xc7, 0x7d, 0x86, 0xb6, 0xad, 0x6d, 0x35, + 0xb5, 0x6a, 0x3e, 0x31, 0x89, 0x79, 0xaf, 0xa2, 0x3f, 0xd0, 0xaa, 0xf9, 0xe9, 0x4d, 0xed, 0xe5, + 0xdb, 0x82, 0xf2, 0xea, 0x6d, 0x41, 0xf9, 0xf3, 0x6d, 0x41, 0x79, 0xfe, 0xae, 0x30, 0xf5, 0xea, + 0x5d, 0x61, 0xea, 0xb7, 0x77, 0x85, 0xa9, 0x2f, 0xae, 0xb7, 0x08, 0x3f, 0xec, 0xee, 0x97, 0x0e, + 0xa8, 0x23, 0xbf, 0x80, 0xe4, 0xbf, 0x9b, 0xcc, 0xfe, 0xb2, 0x7c, 0x24, 0xbe, 0xea, 0x78, 0xbf, + 0x83, 0x99, 0xff, 0xc9, 0x96, 0x14, 0x13, 0x70, 0xfb, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc2, + 0x33, 0x69, 0x7d, 0xf3, 0x0d, 0x00, 0x00, } func (m *WeightedVoteOption) Marshal() (dAtA []byte, err error) { @@ -1134,6 +1147,13 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.FailedReason) > 0 { + i -= len(m.FailedReason) + copy(dAtA[i:], m.FailedReason) + i = encodeVarintGov(dAtA, i, uint64(len(m.FailedReason))) + i-- + dAtA[i] = 0x7a + } if m.Expedited { i-- if m.Expedited { @@ -1768,6 +1788,10 @@ func (m *Proposal) Size() (n int) { if m.Expedited { n += 2 } + l = len(m.FailedReason) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } return n } @@ -2650,6 +2674,38 @@ func (m *Proposal) Unmarshal(dAtA []byte) error { } } m.Expedited = bool(v != 0) + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FailedReason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FailedReason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGov(dAtA[iNdEx:]) diff --git a/x/nft/go.mod b/x/nft/go.mod index 5daa0ca70874b..8e712b153e56c 100644 --- a/x/nft/go.mod +++ b/x/nft/go.mod @@ -25,7 +25,7 @@ require ( require ( cosmossdk.io/collections v0.3.0 // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/x/nft/go.sum b/x/nft/go.sum index 509e4f4186ae7..eaf8e75d3e0f6 100644 --- a/x/nft/go.sum +++ b/x/nft/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/x/upgrade/go.mod b/x/upgrade/go.mod index acfc75e1614c2..5b5a0ed2c08bd 100644 --- a/x/upgrade/go.mod +++ b/x/upgrade/go.mod @@ -35,7 +35,7 @@ require ( cloud.google.com/go/storage v1.30.1 // indirect cosmossdk.io/collections v0.3.0 // indirect cosmossdk.io/math v1.0.1 // indirect - cosmossdk.io/x/tx v0.8.0 // indirect + cosmossdk.io/x/tx v0.9.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect diff --git a/x/upgrade/go.sum b/x/upgrade/go.sum index 6b96028257198..2b44dd4a65094 100644 --- a/x/upgrade/go.sum +++ b/x/upgrade/go.sum @@ -203,8 +203,8 @@ cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ= cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI= -cosmossdk.io/x/tx v0.8.0 h1:gLiGRL/Fy7fs6dd0IX8jOf0PrVr56/SG6XVMGQjyvJU= -cosmossdk.io/x/tx v0.8.0/go.mod h1:T9uEumGNgKU61gJYRv1t3uzQwLnASpJGmSE229HM3xA= +cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI= +cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=