diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cf47be55b..d366028145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Added - [#2107](https://github.com/regen-network/regen-ledger/pull/2107) Add `BurnRegen` method. +- [#2167](https://github.com/regen-network/regen-ledger/pull/2167) Add `CreateUnregisteredProject`, `CreateOrUpdateApplication`, `UpdateProjectEnrollment` and `UpdateProjectFee` methods and `ProjectEnrollment` and `ProjectEnrollments` queries. These additions allow: + - projects to be created without being already enrolled in a credit class + - projects to apply for one or more credit class and for project-credit class relationships to be dynamically managed on-chain + +#### Changed +- [#2167](https://github.com/regen-network/regen-ledger/pull/2167): + - `FormatProjectID` just takes a sequence number and doesn't need a class ID. + - `FormatBatchDenom` requires a class ID because the class is no longer implied by the project ID. + - the credit type `P` is now reserved because this is the new project prefix + - project and batch string validation is now more lenient and just checks for a non-empty string + - `GetCreditTypeFromBatchDenom` takes a `*Denom` parameter instead of a string. + +#### Deprecated +- [#2167](https://github.com/regen-network/regen-ledger/pull/2167): + - `regen.ecocredit.v1.Project.class_key` + - `regen.ecocredit.v1.ProjectSequence` + - `regen.ecocredit.v1.ProjectInfo.class_id` + +#### Removed +- [#2167](https://github.com/regen-network/regen-ledger/pull/2167): the `GetClassIDFromProjectID` and `GetProjectIDFromBatchDenom` have been removed and a state lookup must now be used to resolved these references. + - ## [v5.1.2](https://github.com/regen-network/regen-ledger/releases/tag/v5.1.2) - 2023-06-28 diff --git a/api/regen/ecocredit/v1/query.pulsar.go b/api/regen/ecocredit/v1/query.pulsar.go index 30d5d73ff3..ed0c780004 100644 --- a/api/regen/ecocredit/v1/query.pulsar.go +++ b/api/regen/ecocredit/v1/query.pulsar.go @@ -28506,14 +28506,14 @@ func (x *fastReflection_QueryProjectEnrollmentRequest) ProtoMethods() *protoifac } var ( - md_QueryProjectEnrollmentResponse protoreflect.MessageDescriptor - fd_QueryProjectEnrollmentResponse_project_class protoreflect.FieldDescriptor + md_QueryProjectEnrollmentResponse protoreflect.MessageDescriptor + fd_QueryProjectEnrollmentResponse_enrollment protoreflect.FieldDescriptor ) func init() { file_regen_ecocredit_v1_query_proto_init() md_QueryProjectEnrollmentResponse = File_regen_ecocredit_v1_query_proto.Messages().ByName("QueryProjectEnrollmentResponse") - fd_QueryProjectEnrollmentResponse_project_class = md_QueryProjectEnrollmentResponse.Fields().ByName("project_class") + fd_QueryProjectEnrollmentResponse_enrollment = md_QueryProjectEnrollmentResponse.Fields().ByName("enrollment") } var _ protoreflect.Message = (*fastReflection_QueryProjectEnrollmentResponse)(nil) @@ -28581,9 +28581,9 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) Interface() protoreflect // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_QueryProjectEnrollmentResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.ProjectClass != nil { - value := protoreflect.ValueOfMessage(x.ProjectClass.ProtoReflect()) - if !f(fd_QueryProjectEnrollmentResponse_project_class, value) { + if x.Enrollment != nil { + value := protoreflect.ValueOfMessage(x.Enrollment.ProtoReflect()) + if !f(fd_QueryProjectEnrollmentResponse_enrollment, value) { return } } @@ -28602,8 +28602,8 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) Range(f func(protoreflec // a repeated field is populated if it is non-empty. func (x *fastReflection_QueryProjectEnrollmentResponse) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.project_class": - return x.ProjectClass != nil + case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.enrollment": + return x.Enrollment != nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.QueryProjectEnrollmentResponse")) @@ -28620,8 +28620,8 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) Has(fd protoreflect.Fiel // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryProjectEnrollmentResponse) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.project_class": - x.ProjectClass = nil + case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.enrollment": + x.Enrollment = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.QueryProjectEnrollmentResponse")) @@ -28638,8 +28638,8 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) Clear(fd protoreflect.Fi // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueryProjectEnrollmentResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.project_class": - value := x.ProjectClass + case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.enrollment": + value := x.Enrollment return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { @@ -28661,8 +28661,8 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) Get(descriptor protorefl // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryProjectEnrollmentResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.project_class": - x.ProjectClass = value.Message().Interface().(*ProjectEnrollment) + case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.enrollment": + x.Enrollment = value.Message().Interface().(*EnrollmentInfo) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.QueryProjectEnrollmentResponse")) @@ -28683,11 +28683,11 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) Set(fd protoreflect.Fiel // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryProjectEnrollmentResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.project_class": - if x.ProjectClass == nil { - x.ProjectClass = new(ProjectEnrollment) + case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.enrollment": + if x.Enrollment == nil { + x.Enrollment = new(EnrollmentInfo) } - return protoreflect.ValueOfMessage(x.ProjectClass.ProtoReflect()) + return protoreflect.ValueOfMessage(x.Enrollment.ProtoReflect()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.QueryProjectEnrollmentResponse")) @@ -28701,8 +28701,8 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) Mutable(fd protoreflect. // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueryProjectEnrollmentResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.project_class": - m := new(ProjectEnrollment) + case "regen.ecocredit.v1.QueryProjectEnrollmentResponse.enrollment": + m := new(EnrollmentInfo) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { @@ -28773,8 +28773,8 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) ProtoMethods() *protoifa var n int var l int _ = l - if x.ProjectClass != nil { - l = options.Size(x.ProjectClass) + if x.Enrollment != nil { + l = options.Size(x.Enrollment) n += 1 + l + runtime.Sov(uint64(l)) } if x.unknownFields != nil { @@ -28806,8 +28806,8 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) ProtoMethods() *protoifa i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if x.ProjectClass != nil { - encoded, err := options.Marshal(x.ProjectClass) + if x.Enrollment != nil { + encoded, err := options.Marshal(x.Enrollment) if err != nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -28871,7 +28871,7 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) ProtoMethods() *protoifa switch fieldNum { case 1: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ProjectClass", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Enrollment", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -28898,10 +28898,10 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) ProtoMethods() *protoifa if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - if x.ProjectClass == nil { - x.ProjectClass = &ProjectEnrollment{} + if x.Enrollment == nil { + x.Enrollment = &EnrollmentInfo{} } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.ProjectClass); err != nil { + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Enrollment); err != nil { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex @@ -28943,6 +28943,7 @@ func (x *fastReflection_QueryProjectEnrollmentResponse) ProtoMethods() *protoifa var ( md_QueryProjectEnrollmentsRequest protoreflect.MessageDescriptor fd_QueryProjectEnrollmentsRequest_project_id protoreflect.FieldDescriptor + fd_QueryProjectEnrollmentsRequest_class_id protoreflect.FieldDescriptor fd_QueryProjectEnrollmentsRequest_pagination protoreflect.FieldDescriptor ) @@ -28950,6 +28951,7 @@ func init() { file_regen_ecocredit_v1_query_proto_init() md_QueryProjectEnrollmentsRequest = File_regen_ecocredit_v1_query_proto.Messages().ByName("QueryProjectEnrollmentsRequest") fd_QueryProjectEnrollmentsRequest_project_id = md_QueryProjectEnrollmentsRequest.Fields().ByName("project_id") + fd_QueryProjectEnrollmentsRequest_class_id = md_QueryProjectEnrollmentsRequest.Fields().ByName("class_id") fd_QueryProjectEnrollmentsRequest_pagination = md_QueryProjectEnrollmentsRequest.Fields().ByName("pagination") } @@ -29024,6 +29026,12 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) Range(f func(protoreflec return } } + if x.ClassId != "" { + value := protoreflect.ValueOfString(x.ClassId) + if !f(fd_QueryProjectEnrollmentsRequest_class_id, value) { + return + } + } if x.Pagination != nil { value := protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) if !f(fd_QueryProjectEnrollmentsRequest_pagination, value) { @@ -29047,6 +29055,8 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) Has(fd protoreflect.Fiel switch fd.FullName() { case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.project_id": return x.ProjectId != "" + case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.class_id": + return x.ClassId != "" case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.pagination": return x.Pagination != nil default: @@ -29067,6 +29077,8 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) Clear(fd protoreflect.Fi switch fd.FullName() { case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.project_id": x.ProjectId = "" + case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.class_id": + x.ClassId = "" case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.pagination": x.Pagination = nil default: @@ -29088,6 +29100,9 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) Get(descriptor protorefl case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.project_id": value := x.ProjectId return protoreflect.ValueOfString(value) + case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.class_id": + value := x.ClassId + return protoreflect.ValueOfString(value) case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.pagination": value := x.Pagination return protoreflect.ValueOfMessage(value.ProtoReflect()) @@ -29113,6 +29128,8 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) Set(fd protoreflect.Fiel switch fd.FullName() { case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.project_id": x.ProjectId = value.Interface().(string) + case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.class_id": + x.ClassId = value.Interface().(string) case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.pagination": x.Pagination = value.Message().Interface().(*v1beta1.PageRequest) default: @@ -29142,6 +29159,8 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) Mutable(fd protoreflect. return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.project_id": panic(fmt.Errorf("field project_id of message regen.ecocredit.v1.QueryProjectEnrollmentsRequest is not mutable")) + case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.class_id": + panic(fmt.Errorf("field class_id of message regen.ecocredit.v1.QueryProjectEnrollmentsRequest is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.QueryProjectEnrollmentsRequest")) @@ -29157,6 +29176,8 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) NewField(fd protoreflect switch fd.FullName() { case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.project_id": return protoreflect.ValueOfString("") + case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.class_id": + return protoreflect.ValueOfString("") case "regen.ecocredit.v1.QueryProjectEnrollmentsRequest.pagination": m := new(v1beta1.PageRequest) return protoreflect.ValueOfMessage(m.ProtoReflect()) @@ -29233,6 +29254,10 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) ProtoMethods() *protoifa if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + l = len(x.ClassId) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.Pagination != nil { l = options.Size(x.Pagination) n += 1 + l + runtime.Sov(uint64(l)) @@ -29266,6 +29291,13 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) ProtoMethods() *protoifa i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.ClassId) > 0 { + i -= len(x.ClassId) + copy(dAtA[i:], x.ClassId) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ClassId))) + i-- + dAtA[i] = 0x1a + } if x.Pagination != nil { encoded, err := options.Marshal(x.Pagination) if err != nil { @@ -29368,6 +29400,38 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) ProtoMethods() *protoifa } x.ProjectId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ClassId", 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.ClassId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 2: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) @@ -29442,7 +29506,7 @@ func (x *fastReflection_QueryProjectEnrollmentsRequest) ProtoMethods() *protoifa var _ protoreflect.List = (*_QueryProjectEnrollmentsResponse_1_list)(nil) type _QueryProjectEnrollmentsResponse_1_list struct { - list *[]*ProjectEnrollment + list *[]*EnrollmentInfo } func (x *_QueryProjectEnrollmentsResponse_1_list) Len() int { @@ -29458,18 +29522,18 @@ func (x *_QueryProjectEnrollmentsResponse_1_list) Get(i int) protoreflect.Value func (x *_QueryProjectEnrollmentsResponse_1_list) Set(i int, value protoreflect.Value) { valueUnwrapped := value.Message() - concreteValue := valueUnwrapped.Interface().(*ProjectEnrollment) + concreteValue := valueUnwrapped.Interface().(*EnrollmentInfo) (*x.list)[i] = concreteValue } func (x *_QueryProjectEnrollmentsResponse_1_list) Append(value protoreflect.Value) { valueUnwrapped := value.Message() - concreteValue := valueUnwrapped.Interface().(*ProjectEnrollment) + concreteValue := valueUnwrapped.Interface().(*EnrollmentInfo) *x.list = append(*x.list, concreteValue) } func (x *_QueryProjectEnrollmentsResponse_1_list) AppendMutable() protoreflect.Value { - v := new(ProjectEnrollment) + v := new(EnrollmentInfo) *x.list = append(*x.list, v) return protoreflect.ValueOfMessage(v.ProtoReflect()) } @@ -29482,7 +29546,7 @@ func (x *_QueryProjectEnrollmentsResponse_1_list) Truncate(n int) { } func (x *_QueryProjectEnrollmentsResponse_1_list) NewElement() protoreflect.Value { - v := new(ProjectEnrollment) + v := new(EnrollmentInfo) return protoreflect.ValueOfMessage(v.ProtoReflect()) } @@ -29692,7 +29756,7 @@ func (x *fastReflection_QueryProjectEnrollmentsResponse) Mutable(fd protoreflect switch fd.FullName() { case "regen.ecocredit.v1.QueryProjectEnrollmentsResponse.enrollments": if x.Enrollments == nil { - x.Enrollments = []*ProjectEnrollment{} + x.Enrollments = []*EnrollmentInfo{} } value := &_QueryProjectEnrollmentsResponse_1_list{list: &x.Enrollments} return protoreflect.ValueOfList(value) @@ -29715,7 +29779,7 @@ func (x *fastReflection_QueryProjectEnrollmentsResponse) Mutable(fd protoreflect func (x *fastReflection_QueryProjectEnrollmentsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { case "regen.ecocredit.v1.QueryProjectEnrollmentsResponse.enrollments": - list := []*ProjectEnrollment{} + list := []*EnrollmentInfo{} return protoreflect.ValueOfList(&_QueryProjectEnrollmentsResponse_1_list{list: &list}) case "regen.ecocredit.v1.QueryProjectEnrollmentsResponse.pagination": m := new(v1beta1.PageResponse) @@ -29897,21 +29961,687 @@ func (x *fastReflection_QueryProjectEnrollmentsResponse) ProtoMethods() *protoif if b < 0x80 { break } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryProjectEnrollmentsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryProjectEnrollmentsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryProjectEnrollmentsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryProjectEnrollmentsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Enrollments", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + 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.Enrollments = append(x.Enrollments, &EnrollmentInfo{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Enrollments[len(x.Enrollments)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + 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 + } + if x.Pagination == nil { + x.Pagination = &v1beta1.PageResponse{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_EnrollmentInfo protoreflect.MessageDescriptor + fd_EnrollmentInfo_project_id protoreflect.FieldDescriptor + fd_EnrollmentInfo_class_id protoreflect.FieldDescriptor + fd_EnrollmentInfo_status protoreflect.FieldDescriptor + fd_EnrollmentInfo_application_metadata protoreflect.FieldDescriptor + fd_EnrollmentInfo_enrollment_metadata protoreflect.FieldDescriptor +) + +func init() { + file_regen_ecocredit_v1_query_proto_init() + md_EnrollmentInfo = File_regen_ecocredit_v1_query_proto.Messages().ByName("EnrollmentInfo") + fd_EnrollmentInfo_project_id = md_EnrollmentInfo.Fields().ByName("project_id") + fd_EnrollmentInfo_class_id = md_EnrollmentInfo.Fields().ByName("class_id") + fd_EnrollmentInfo_status = md_EnrollmentInfo.Fields().ByName("status") + fd_EnrollmentInfo_application_metadata = md_EnrollmentInfo.Fields().ByName("application_metadata") + fd_EnrollmentInfo_enrollment_metadata = md_EnrollmentInfo.Fields().ByName("enrollment_metadata") +} + +var _ protoreflect.Message = (*fastReflection_EnrollmentInfo)(nil) + +type fastReflection_EnrollmentInfo EnrollmentInfo + +func (x *EnrollmentInfo) ProtoReflect() protoreflect.Message { + return (*fastReflection_EnrollmentInfo)(x) +} + +func (x *EnrollmentInfo) slowProtoReflect() protoreflect.Message { + mi := &file_regen_ecocredit_v1_query_proto_msgTypes[60] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_EnrollmentInfo_messageType fastReflection_EnrollmentInfo_messageType +var _ protoreflect.MessageType = fastReflection_EnrollmentInfo_messageType{} + +type fastReflection_EnrollmentInfo_messageType struct{} + +func (x fastReflection_EnrollmentInfo_messageType) Zero() protoreflect.Message { + return (*fastReflection_EnrollmentInfo)(nil) +} +func (x fastReflection_EnrollmentInfo_messageType) New() protoreflect.Message { + return new(fastReflection_EnrollmentInfo) +} +func (x fastReflection_EnrollmentInfo_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_EnrollmentInfo +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_EnrollmentInfo) Descriptor() protoreflect.MessageDescriptor { + return md_EnrollmentInfo +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_EnrollmentInfo) Type() protoreflect.MessageType { + return _fastReflection_EnrollmentInfo_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_EnrollmentInfo) New() protoreflect.Message { + return new(fastReflection_EnrollmentInfo) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_EnrollmentInfo) Interface() protoreflect.ProtoMessage { + return (*EnrollmentInfo)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_EnrollmentInfo) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.ProjectId != "" { + value := protoreflect.ValueOfString(x.ProjectId) + if !f(fd_EnrollmentInfo_project_id, value) { + return + } + } + if x.ClassId != "" { + value := protoreflect.ValueOfString(x.ClassId) + if !f(fd_EnrollmentInfo_class_id, value) { + return + } + } + if x.Status != 0 { + value := protoreflect.ValueOfEnum((protoreflect.EnumNumber)(x.Status)) + if !f(fd_EnrollmentInfo_status, value) { + return + } + } + if x.ApplicationMetadata != "" { + value := protoreflect.ValueOfString(x.ApplicationMetadata) + if !f(fd_EnrollmentInfo_application_metadata, value) { + return + } + } + if x.EnrollmentMetadata != "" { + value := protoreflect.ValueOfString(x.EnrollmentMetadata) + if !f(fd_EnrollmentInfo_enrollment_metadata, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_EnrollmentInfo) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "regen.ecocredit.v1.EnrollmentInfo.project_id": + return x.ProjectId != "" + case "regen.ecocredit.v1.EnrollmentInfo.class_id": + return x.ClassId != "" + case "regen.ecocredit.v1.EnrollmentInfo.status": + return x.Status != 0 + case "regen.ecocredit.v1.EnrollmentInfo.application_metadata": + return x.ApplicationMetadata != "" + case "regen.ecocredit.v1.EnrollmentInfo.enrollment_metadata": + return x.EnrollmentMetadata != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.EnrollmentInfo")) + } + panic(fmt.Errorf("message regen.ecocredit.v1.EnrollmentInfo does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EnrollmentInfo) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "regen.ecocredit.v1.EnrollmentInfo.project_id": + x.ProjectId = "" + case "regen.ecocredit.v1.EnrollmentInfo.class_id": + x.ClassId = "" + case "regen.ecocredit.v1.EnrollmentInfo.status": + x.Status = 0 + case "regen.ecocredit.v1.EnrollmentInfo.application_metadata": + x.ApplicationMetadata = "" + case "regen.ecocredit.v1.EnrollmentInfo.enrollment_metadata": + x.EnrollmentMetadata = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.EnrollmentInfo")) + } + panic(fmt.Errorf("message regen.ecocredit.v1.EnrollmentInfo does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_EnrollmentInfo) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "regen.ecocredit.v1.EnrollmentInfo.project_id": + value := x.ProjectId + return protoreflect.ValueOfString(value) + case "regen.ecocredit.v1.EnrollmentInfo.class_id": + value := x.ClassId + return protoreflect.ValueOfString(value) + case "regen.ecocredit.v1.EnrollmentInfo.status": + value := x.Status + return protoreflect.ValueOfEnum((protoreflect.EnumNumber)(value)) + case "regen.ecocredit.v1.EnrollmentInfo.application_metadata": + value := x.ApplicationMetadata + return protoreflect.ValueOfString(value) + case "regen.ecocredit.v1.EnrollmentInfo.enrollment_metadata": + value := x.EnrollmentMetadata + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.EnrollmentInfo")) + } + panic(fmt.Errorf("message regen.ecocredit.v1.EnrollmentInfo does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EnrollmentInfo) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "regen.ecocredit.v1.EnrollmentInfo.project_id": + x.ProjectId = value.Interface().(string) + case "regen.ecocredit.v1.EnrollmentInfo.class_id": + x.ClassId = value.Interface().(string) + case "regen.ecocredit.v1.EnrollmentInfo.status": + x.Status = (ProjectEnrollmentStatus)(value.Enum()) + case "regen.ecocredit.v1.EnrollmentInfo.application_metadata": + x.ApplicationMetadata = value.Interface().(string) + case "regen.ecocredit.v1.EnrollmentInfo.enrollment_metadata": + x.EnrollmentMetadata = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.EnrollmentInfo")) + } + panic(fmt.Errorf("message regen.ecocredit.v1.EnrollmentInfo does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EnrollmentInfo) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "regen.ecocredit.v1.EnrollmentInfo.project_id": + panic(fmt.Errorf("field project_id of message regen.ecocredit.v1.EnrollmentInfo is not mutable")) + case "regen.ecocredit.v1.EnrollmentInfo.class_id": + panic(fmt.Errorf("field class_id of message regen.ecocredit.v1.EnrollmentInfo is not mutable")) + case "regen.ecocredit.v1.EnrollmentInfo.status": + panic(fmt.Errorf("field status of message regen.ecocredit.v1.EnrollmentInfo is not mutable")) + case "regen.ecocredit.v1.EnrollmentInfo.application_metadata": + panic(fmt.Errorf("field application_metadata of message regen.ecocredit.v1.EnrollmentInfo is not mutable")) + case "regen.ecocredit.v1.EnrollmentInfo.enrollment_metadata": + panic(fmt.Errorf("field enrollment_metadata of message regen.ecocredit.v1.EnrollmentInfo is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.EnrollmentInfo")) + } + panic(fmt.Errorf("message regen.ecocredit.v1.EnrollmentInfo does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_EnrollmentInfo) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "regen.ecocredit.v1.EnrollmentInfo.project_id": + return protoreflect.ValueOfString("") + case "regen.ecocredit.v1.EnrollmentInfo.class_id": + return protoreflect.ValueOfString("") + case "regen.ecocredit.v1.EnrollmentInfo.status": + return protoreflect.ValueOfEnum(0) + case "regen.ecocredit.v1.EnrollmentInfo.application_metadata": + return protoreflect.ValueOfString("") + case "regen.ecocredit.v1.EnrollmentInfo.enrollment_metadata": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.EnrollmentInfo")) + } + panic(fmt.Errorf("message regen.ecocredit.v1.EnrollmentInfo does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_EnrollmentInfo) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in regen.ecocredit.v1.EnrollmentInfo", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_EnrollmentInfo) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EnrollmentInfo) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_EnrollmentInfo) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_EnrollmentInfo) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*EnrollmentInfo) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.ProjectId) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.ClassId) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Status != 0 { + n += 1 + runtime.Sov(uint64(x.Status)) + } + l = len(x.ApplicationMetadata) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.EnrollmentMetadata) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*EnrollmentInfo) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.EnrollmentMetadata) > 0 { + i -= len(x.EnrollmentMetadata) + copy(dAtA[i:], x.EnrollmentMetadata) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.EnrollmentMetadata))) + i-- + dAtA[i] = 0x32 + } + if len(x.ApplicationMetadata) > 0 { + i -= len(x.ApplicationMetadata) + copy(dAtA[i:], x.ApplicationMetadata) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ApplicationMetadata))) + i-- + dAtA[i] = 0x2a + } + if x.Status != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Status)) + i-- + dAtA[i] = 0x20 + } + if len(x.ClassId) > 0 { + i -= len(x.ClassId) + copy(dAtA[i:], x.ClassId) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ClassId))) + i-- + dAtA[i] = 0x12 + } + if len(x.ProjectId) > 0 { + i -= len(x.ProjectId) + copy(dAtA[i:], x.ProjectId) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ProjectId))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*EnrollmentInfo) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire 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++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: EnrollmentInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: EnrollmentInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ProjectId", 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.ProjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ClassId", 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.ClassId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + x.Status = 0 + 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++ + x.Status |= ProjectEnrollmentStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Enrollments", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ApplicationMetadata", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -29921,31 +30651,29 @@ func (x *fastReflection_QueryProjectEnrollmentsResponse) ProtoMethods() *protoif } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - postIndex := iNdEx + msglen + 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.Enrollments = append(x.Enrollments, &ProjectEnrollment{}) - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Enrollments[len(x.Enrollments)-1]); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } + x.ApplicationMetadata = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 6: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field EnrollmentMetadata", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -29955,27 +30683,23 @@ func (x *fastReflection_QueryProjectEnrollmentsResponse) ProtoMethods() *protoif } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - postIndex := iNdEx + msglen + 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 } - if x.Pagination == nil { - x.Pagination = &v1beta1.PageResponse{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } + x.EnrollmentMetadata = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -31967,8 +32691,9 @@ type ProjectInfo struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // admin is the admin of the project. Admin string `protobuf:"bytes,2,opt,name=admin,proto3" json:"admin,omitempty"` - // class_id is the unique identifier of the credit class within which the - // project was created. + // Deprecated: use ProjectEnrollment instead. + // + // Deprecated: Do not use. ClassId string `protobuf:"bytes,3,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` // jurisdiction is the jurisdiction of the project. Full documentation can be // found in MsgCreateProject.jurisdiction. @@ -32013,6 +32738,7 @@ func (x *ProjectInfo) GetAdmin() string { return "" } +// Deprecated: Do not use. func (x *ProjectInfo) GetClassId() string { if x != nil { return x.ClassId @@ -32580,7 +33306,7 @@ type QueryProjectEnrollmentResponse struct { unknownFields protoimpl.UnknownFields // project_class is the fetched project class relationship. - ProjectClass *ProjectEnrollment `protobuf:"bytes,1,opt,name=project_class,json=projectClass,proto3" json:"project_class,omitempty"` + Enrollment *EnrollmentInfo `protobuf:"bytes,1,opt,name=enrollment,proto3" json:"enrollment,omitempty"` } func (x *QueryProjectEnrollmentResponse) Reset() { @@ -32603,9 +33329,9 @@ func (*QueryProjectEnrollmentResponse) Descriptor() ([]byte, []int) { return file_regen_ecocredit_v1_query_proto_rawDescGZIP(), []int{57} } -func (x *QueryProjectEnrollmentResponse) GetProjectClass() *ProjectEnrollment { +func (x *QueryProjectEnrollmentResponse) GetEnrollment() *EnrollmentInfo { if x != nil { - return x.ProjectClass + return x.Enrollment } return nil } @@ -32618,8 +33344,12 @@ type QueryProjectEnrollmentsRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // project_id is the unique identifier of the project to query. + // project_id is the unique identifier of the project to filter enrollments + // by. If not set, enrollments for all projects will be returned. ProjectId string `protobuf:"bytes,1,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + // class_id is the unique identifier of the credit class to filter enrollments + // by. If not set, enrollments for all credit classes will be returned. + ClassId string `protobuf:"bytes,3,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` // pagination defines an optional pagination for the request. Pagination *v1beta1.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -32651,6 +33381,13 @@ func (x *QueryProjectEnrollmentsRequest) GetProjectId() string { return "" } +func (x *QueryProjectEnrollmentsRequest) GetClassId() string { + if x != nil { + return x.ClassId + } + return "" +} + func (x *QueryProjectEnrollmentsRequest) GetPagination() *v1beta1.PageRequest { if x != nil { return x.Pagination @@ -32667,7 +33404,7 @@ type QueryProjectEnrollmentsResponse struct { unknownFields protoimpl.UnknownFields // enrollments are the fetched project credit class enrollments. - Enrollments []*ProjectEnrollment `protobuf:"bytes,1,rep,name=enrollments,proto3" json:"enrollments,omitempty"` + Enrollments []*EnrollmentInfo `protobuf:"bytes,1,rep,name=enrollments,proto3" json:"enrollments,omitempty"` // pagination defines the pagination in the response. Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -32692,7 +33429,7 @@ func (*QueryProjectEnrollmentsResponse) Descriptor() ([]byte, []int) { return file_regen_ecocredit_v1_query_proto_rawDescGZIP(), []int{59} } -func (x *QueryProjectEnrollmentsResponse) GetEnrollments() []*ProjectEnrollment { +func (x *QueryProjectEnrollmentsResponse) GetEnrollments() []*EnrollmentInfo { if x != nil { return x.Enrollments } @@ -32706,6 +33443,81 @@ func (x *QueryProjectEnrollmentsResponse) GetPagination() *v1beta1.PageResponse return nil } +// EnrollmentInfo is the human-readable project enrollment information. +type EnrollmentInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // project_id is the unique identifier of the project to query. + ProjectId string `protobuf:"bytes,1,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + // class_id is the unique identifier of the credit class to query. + ClassId string `protobuf:"bytes,2,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` + // status is the status of the enrollment. + Status ProjectEnrollmentStatus `protobuf:"varint,4,opt,name=status,proto3,enum=regen.ecocredit.v1.ProjectEnrollmentStatus" json:"status,omitempty"` + // application_metadata is any arbitrary metadata set by the project + // admin related to its application to the credit class. + ApplicationMetadata string `protobuf:"bytes,5,opt,name=application_metadata,json=applicationMetadata,proto3" json:"application_metadata,omitempty"` + // enrollment_metadata is any arbitrary metadata set by the credit class + // admin evaluating the project's application to the credit class. + EnrollmentMetadata string `protobuf:"bytes,6,opt,name=enrollment_metadata,json=enrollmentMetadata,proto3" json:"enrollment_metadata,omitempty"` +} + +func (x *EnrollmentInfo) Reset() { + *x = EnrollmentInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_regen_ecocredit_v1_query_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnrollmentInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnrollmentInfo) ProtoMessage() {} + +// Deprecated: Use EnrollmentInfo.ProtoReflect.Descriptor instead. +func (*EnrollmentInfo) Descriptor() ([]byte, []int) { + return file_regen_ecocredit_v1_query_proto_rawDescGZIP(), []int{60} +} + +func (x *EnrollmentInfo) GetProjectId() string { + if x != nil { + return x.ProjectId + } + return "" +} + +func (x *EnrollmentInfo) GetClassId() string { + if x != nil { + return x.ClassId + } + return "" +} + +func (x *EnrollmentInfo) GetStatus() ProjectEnrollmentStatus { + if x != nil { + return x.Status + } + return ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_UNSPECIFIED +} + +func (x *EnrollmentInfo) GetApplicationMetadata() string { + if x != nil { + return x.ApplicationMetadata + } + return "" +} + +func (x *EnrollmentInfo) GetEnrollmentMetadata() string { + if x != nil { + return x.EnrollmentMetadata + } + return "" +} + var File_regen_ecocredit_v1_query_proto protoreflect.FileDescriptor var file_regen_ecocredit_v1_query_proto_rawDesc = []byte{ @@ -33050,474 +33862,490 @@ var file_regen_ecocredit_v1_query_proto_rawDesc = []byte{ 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x41, 0x62, 0x62, 0x72, 0x65, 0x76, 0x22, 0xb1, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x41, 0x62, 0x62, 0x72, 0x65, 0x76, 0x22, 0xb5, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x75, 0x72, 0x69, - 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 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, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0xbb, 0x02, 0x0a, 0x09, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, - 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, - 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x35, 0x0a, - 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x1d, 0x0a, + 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, + 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 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, 0x12, 0x21, 0x0a, 0x0c, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, + 0xbb, 0x02, 0x0a, 0x09, 0x42, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, + 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, + 0x65, 0x12, 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x07, 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x6e, 0x64, - 0x44, 0x61, 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, - 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x10, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, - 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, - 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, - 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x69, - 0x72, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x73, 0x63, - 0x72, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x23, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e, 0x0a, 0x22, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, - 0x77, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x6a, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x93, 0x01, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, - 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x44, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, - 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x03, 0x66, 0x65, - 0x65, 0x18, 0x01, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, 0x0a, 0x20, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, - 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, - 0x0a, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, - 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, - 0x6e, 0x73, 0x22, 0x59, 0x0a, 0x1d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x22, 0x6c, 0x0a, - 0x1e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4a, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x87, 0x01, 0x0a, 0x1e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, - 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x46, 0x0a, - 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb3, 0x01, 0x0a, 0x1f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x69, 0x73, 0x73, + 0x75, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, + 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x22, 0xc6, 0x01, + 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x27, 0x0a, + 0x0f, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, + 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, + 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, + 0x0f, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x65, 0x64, + 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x23, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, + 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e, 0x0a, 0x22, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, + 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x6a, 0x0a, 0x20, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x93, 0x01, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, + 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x44, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, + 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x01, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, + 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x22, 0x59, 0x0a, 0x1d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x65, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xc1, 0x2a, 0x0a, 0x05, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x81, 0x01, 0x0a, 0x07, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, - 0x73, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, - 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x72, - 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, - 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x12, 0xd4, 0x01, 0x0a, 0x0e, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x65, 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x2e, 0x2e, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, + 0x64, 0x22, 0x64, 0x0a, 0x1e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x65, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xa2, 0x01, 0x0a, 0x1e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x49, 0x64, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb0, 0x01, 0x0a, + 0x1f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x44, 0x0a, 0x0b, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, + 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x65, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0xf3, 0x01, 0x0a, 0x0e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x42, 0x79, - 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, + 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, + 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x31, 0x0a, 0x14, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x13, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x13, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x12, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x32, 0xc1, 0x2a, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x81, 0x01, 0x0a, 0x07, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x65, 0x73, 0x12, 0xd4, 0x01, 0x0a, 0x0e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x42, + 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x2e, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5b, 0x5a, + 0x2b, 0x12, 0x29, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x2f, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x7b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x7d, 0x12, 0x2c, 0x2f, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, + 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x2f, 0x7b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x7d, 0x12, 0xae, 0x01, 0x0a, 0x05, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x56, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50, 0x5a, 0x28, 0x12, 0x26, 0x2f, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, + 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x24, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, + 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xd3, 0x01, 0x0a, 0x0c, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x42, 0x79, - 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x5b, 0x5a, 0x2b, 0x12, 0x29, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x65, 0x73, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x7b, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x7d, 0x12, 0x2c, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x2d, - 0x62, 0x79, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x7b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x7d, - 0x12, 0xae, 0x01, 0x0a, 0x05, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x65, 0x67, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x50, 0x5a, 0x28, 0x12, 0x26, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x60, 0x5a, 0x30, 0x12, 0x2e, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, - 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x24, 0x2f, 0x72, 0x65, + 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x69, 0x73, 0x73, 0x75, + 0x65, 0x72, 0x73, 0x12, 0x2c, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2d, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, + 0x7d, 0x12, 0x85, 0x01, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x28, + 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, - 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, - 0x7d, 0x12, 0xd3, 0x01, 0x0a, 0x0c, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, - 0x72, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, - 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x66, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x60, 0x5a, 0x30, 0x12, 0x2e, 0x2f, 0x72, 0x65, 0x67, 0x65, - 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x2f, 0x72, 0x65, 0x67, 0x65, - 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x2d, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x85, 0x01, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, + 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x94, 0x02, 0x0a, 0x0f, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x2f, 0x2e, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1e, 0x12, 0x1c, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, - 0x94, 0x02, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9d, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x96, 0x01, - 0x5a, 0x2f, 0x12, 0x2d, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, - 0x7d, 0x5a, 0x31, 0x12, 0x2f, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, - 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x87, 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, - 0x12, 0x35, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x7f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x79, 0x5a, 0x3a, 0x12, 0x38, 0x2f, 0x72, 0x65, 0x67, 0x65, - 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x2d, 0x69, 0x64, 0x2f, 0x7b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x12, 0x3b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2d, 0x69, - 0x64, 0x2f, 0x7b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x12, 0xd9, 0x01, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x41, - 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x63, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5d, 0x5a, - 0x2c, 0x12, 0x2a, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x7b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x7d, 0x12, 0x2d, 0x2f, + 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x9d, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x96, 0x01, 0x5a, 0x2f, 0x12, 0x2d, 0x2f, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, + 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x5a, 0x31, 0x12, 0x2f, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x7b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x7d, 0x12, 0xbb, 0x01, 0x0a, - 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, - 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, + 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, + 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2d, 0x62, 0x79, 0x2d, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, + 0x12, 0x87, 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x35, 0x2e, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x36, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5d, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x57, 0x5a, 0x2b, 0x12, 0x29, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, - 0x12, 0x28, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x81, 0x01, 0x0a, 0x07, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1d, 0x12, 0x1b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0xdb, - 0x01, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x49, 0x73, 0x73, 0x75, - 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5f, 0x5a, 0x2d, 0x12, - 0x2b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x69, 0x73, 0x73, - 0x75, 0x65, 0x72, 0x2f, 0x7b, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x7d, 0x12, 0x2e, 0x2f, 0x72, - 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, - 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x69, 0x73, 0x73, - 0x75, 0x65, 0x72, 0x2f, 0x7b, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x7d, 0x12, 0xda, 0x01, 0x0a, - 0x0e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, - 0x2e, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x61, 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x72, 0x65, 0x67, - 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, - 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x2f, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, - 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xe8, 0x01, 0x0a, 0x10, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x30, - 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, - 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x6f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x69, 0x5a, 0x32, 0x12, 0x30, 0x2f, + 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7f, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x79, 0x5a, 0x3a, 0x12, 0x38, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x2f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x2f, 0x7b, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x3b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, - 0x33, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xb4, 0x01, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x25, + 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x2f, 0x7b, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xd9, 0x01, 0x0a, 0x0f, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5c, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x56, 0x5a, 0x2b, 0x12, 0x29, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, - 0x6d, 0x7d, 0x12, 0x27, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x7b, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x12, 0x98, 0x02, 0x0a, 0x07, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb9, 0x01, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0xb2, 0x01, 0x5a, 0x3d, 0x12, 0x3b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, - 0x7d, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x7d, 0x5a, 0x3c, 0x12, 0x3a, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x2f, 0x62, 0x61, - 0x74, 0x63, 0x68, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, - 0x7d, 0x12, 0x33, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x7b, - 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x2f, 0x7b, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x8f, 0x01, 0x0a, 0x08, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, - 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, - 0x12, 0x26, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0xe7, 0x01, 0x0a, 0x0f, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x42, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2f, 0x2e, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x42, 0x79, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x63, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5d, 0x5a, 0x2c, 0x12, 0x2a, 0x2f, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, + 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, + 0x7b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x7d, 0x12, 0x2d, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x7b, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x57, 0x5a, 0x2b, 0x12, + 0x29, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x28, 0x2f, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x81, 0x01, 0x0a, 0x07, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, + 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, + 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0xdb, 0x01, 0x0a, 0x0f, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x42, - 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, + 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x42, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x71, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6b, 0x5a, 0x34, 0x12, 0x32, 0x2f, 0x72, 0x65, 0x67, 0x65, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, + 0x79, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5f, 0x5a, 0x2d, 0x12, 0x2b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, - 0x6e, 0x6f, 0x6d, 0x7d, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x33, 0x2f, - 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, - 0x6d, 0x7d, 0x12, 0xb2, 0x01, 0x0a, 0x0b, 0x41, 0x6c, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x42, 0x5a, 0x1e, 0x12, 0x1c, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x20, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x6c, 0x6c, 0x2d, 0x62, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0xbf, 0x01, 0x0a, 0x06, 0x53, 0x75, 0x70, 0x70, - 0x6c, 0x79, 0x12, 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x65, 0x67, - 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5e, 0x5a, 0x32, 0x12, 0x30, 0x2f, - 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, - 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x2f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, - 0x28, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x2f, 0x7b, 0x62, 0x61, 0x74, - 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x12, 0x92, 0x01, 0x0a, 0x0b, 0x43, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x2f, 0x7b, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x72, 0x7d, 0x12, 0x2e, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x2f, 0x7b, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x72, 0x7d, 0x12, 0xda, 0x01, 0x0a, 0x0e, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x72, + 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x67, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x61, 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, + 0x64, 0x7d, 0x12, 0x2f, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2d, + 0x62, 0x79, 0x2d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, + 0x69, 0x64, 0x7d, 0x12, 0xe8, 0x01, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, + 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x42, 0x79, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6f, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x69, 0x5a, 0x32, 0x12, 0x30, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x33, 0x2f, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xb4, + 0x01, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x56, 0x5a, + 0x2b, 0x12, 0x29, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x7b, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x12, 0x27, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, - 0x31, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x12, 0x80, - 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, + 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x12, 0x98, 0x02, 0x0a, 0x07, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb9, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0xb2, 0x01, 0x5a, 0x3d, + 0x12, 0x3b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x7b, 0x62, + 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x2f, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x5a, 0x3c, 0x12, + 0x3a, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x7b, 0x62, + 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x12, 0x33, 0x2f, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, + 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, + 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, + 0x12, 0x8f, 0x01, 0x0a, 0x08, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x28, 0x2e, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x7d, 0x12, 0xe7, 0x01, 0x0a, 0x0f, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x42, + 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x42, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x42, 0x79, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x6b, 0x5a, 0x34, 0x12, 0x32, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, + 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x2f, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x33, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2d, 0x62, 0x79, 0x2d, 0x62, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x7b, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x7d, 0x12, 0xb2, 0x01, 0x0a, + 0x0b, 0x41, 0x6c, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x88, 0x02, - 0x01, 0x12, 0xd0, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, + 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x42, 0x5a, + 0x1e, 0x12, 0x1c, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, + 0x20, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x6c, 0x6c, 0x2d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x12, 0xbf, 0x01, 0x0a, 0x06, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x63, 0x5a, 0x31, 0x12, 0x2f, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2d, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x2e, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2d, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x7b, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x15, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x35, - 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, + 0x75, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x5e, 0x5a, 0x32, 0x12, 0x30, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, + 0x6d, 0x7d, 0x2f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x28, 0x2f, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, + 0x75, 0x70, 0x70, 0x6c, 0x79, 0x2f, 0x7b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, + 0x6f, 0x6d, 0x7d, 0x12, 0x92, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x12, 0x80, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, + 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x88, 0x02, 0x01, 0x12, 0xd0, 0x01, 0x0a, 0x0a, + 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x2e, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x69, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x63, 0x5a, 0x31, 0x12, 0x2f, 0x2f, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, + 0x76, 0x31, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, + 0x7b, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x2e, + 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x2f, + 0x7b, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0xbb, + 0x01, 0x0a, 0x15, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, + 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x35, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, + 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x36, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x12, + 0x2b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x6f, 0x72, 0x2d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x12, 0xb7, 0x01, 0x0a, + 0x14, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x34, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, - 0x77, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x12, 0x2b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x2d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, - 0x73, 0x74, 0x12, 0xb7, 0x01, 0x0a, 0x14, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x34, 0x2e, 0x72, 0x65, + 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, - 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x35, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, - 0x12, 0x2a, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x2d, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x86, 0x01, 0x0a, - 0x08, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x12, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, - 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, + 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x2d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2d, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x86, 0x01, 0x0a, 0x08, 0x43, 0x6c, 0x61, 0x73, 0x73, + 0x46, 0x65, 0x65, 0x12, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x2d, 0x66, 0x65, 0x65, 0x12, 0xb3, 0x01, 0x0a, 0x13, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, - 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x33, 0x2e, + 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, - 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, - 0x12, 0x29, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x2d, 0x62, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0xc3, 0x01, 0x0a, 0x11, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x31, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, - 0x12, 0x3f, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, - 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x32, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, - 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, + 0x12, 0x1d, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2d, 0x66, 0x65, 0x65, 0x12, + 0xb3, 0x01, 0x0a, 0x13, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x12, 0x34, 0x2f, 0x72, 0x65, 0x67, 0x65, - 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, - 0xd8, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x45, 0x58, 0xaa, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, - 0x2e, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, - 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, - 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x3a, 0x3a, 0x45, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29, 0x2f, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x2d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2d, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0xc3, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x2e, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, + 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x12, 0x3f, 0x2f, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2f, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x12, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x32, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x36, 0x12, 0x34, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x65, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0xd8, 0x01, 0x0a, 0x16, 0x63, 0x6f, + 0x6d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2d, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, + 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, + 0x3b, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, + 0x45, 0x58, 0xaa, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x45, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, + 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x52, + 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, + 0x52, 0x65, 0x67, 0x65, 0x6e, 0x3a, 0x3a, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -33532,7 +34360,7 @@ func file_regen_ecocredit_v1_query_proto_rawDescGZIP() []byte { return file_regen_ecocredit_v1_query_proto_rawDescData } -var file_regen_ecocredit_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 60) +var file_regen_ecocredit_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 61) var file_regen_ecocredit_v1_query_proto_goTypes = []interface{}{ (*QueryClassesRequest)(nil), // 0: regen.ecocredit.v1.QueryClassesRequest (*QueryClassesResponse)(nil), // 1: regen.ecocredit.v1.QueryClassesResponse @@ -33594,134 +34422,136 @@ var file_regen_ecocredit_v1_query_proto_goTypes = []interface{}{ (*QueryProjectEnrollmentResponse)(nil), // 57: regen.ecocredit.v1.QueryProjectEnrollmentResponse (*QueryProjectEnrollmentsRequest)(nil), // 58: regen.ecocredit.v1.QueryProjectEnrollmentsRequest (*QueryProjectEnrollmentsResponse)(nil), // 59: regen.ecocredit.v1.QueryProjectEnrollmentsResponse - (*v1beta1.PageRequest)(nil), // 60: cosmos.base.query.v1beta1.PageRequest - (*v1beta1.PageResponse)(nil), // 61: cosmos.base.query.v1beta1.PageResponse - (*CreditType)(nil), // 62: regen.ecocredit.v1.CreditType - (*Params)(nil), // 63: regen.ecocredit.v1.Params - (*timestamppb.Timestamp)(nil), // 64: google.protobuf.Timestamp - (*v1beta11.Coin)(nil), // 65: cosmos.base.v1beta1.Coin - (*ProjectEnrollment)(nil), // 66: regen.ecocredit.v1.ProjectEnrollment + (*EnrollmentInfo)(nil), // 60: regen.ecocredit.v1.EnrollmentInfo + (*v1beta1.PageRequest)(nil), // 61: cosmos.base.query.v1beta1.PageRequest + (*v1beta1.PageResponse)(nil), // 62: cosmos.base.query.v1beta1.PageResponse + (*CreditType)(nil), // 63: regen.ecocredit.v1.CreditType + (*Params)(nil), // 64: regen.ecocredit.v1.Params + (*timestamppb.Timestamp)(nil), // 65: google.protobuf.Timestamp + (*v1beta11.Coin)(nil), // 66: cosmos.base.v1beta1.Coin + (ProjectEnrollmentStatus)(0), // 67: regen.ecocredit.v1.ProjectEnrollmentStatus } var file_regen_ecocredit_v1_query_proto_depIdxs = []int32{ - 60, // 0: regen.ecocredit.v1.QueryClassesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 61, // 0: regen.ecocredit.v1.QueryClassesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 44, // 1: regen.ecocredit.v1.QueryClassesResponse.classes:type_name -> regen.ecocredit.v1.ClassInfo - 61, // 2: regen.ecocredit.v1.QueryClassesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 3: regen.ecocredit.v1.QueryClassesByAdminRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 2: regen.ecocredit.v1.QueryClassesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 3: regen.ecocredit.v1.QueryClassesByAdminRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 44, // 4: regen.ecocredit.v1.QueryClassesByAdminResponse.classes:type_name -> regen.ecocredit.v1.ClassInfo - 61, // 5: regen.ecocredit.v1.QueryClassesByAdminResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 62, // 5: regen.ecocredit.v1.QueryClassesByAdminResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse 44, // 6: regen.ecocredit.v1.QueryClassResponse.class:type_name -> regen.ecocredit.v1.ClassInfo - 60, // 7: regen.ecocredit.v1.QueryClassIssuersRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest - 61, // 8: regen.ecocredit.v1.QueryClassIssuersResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 9: regen.ecocredit.v1.QueryProjectsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 61, // 7: regen.ecocredit.v1.QueryClassIssuersRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 8: regen.ecocredit.v1.QueryClassIssuersResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 9: regen.ecocredit.v1.QueryProjectsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 45, // 10: regen.ecocredit.v1.QueryProjectsResponse.projects:type_name -> regen.ecocredit.v1.ProjectInfo - 61, // 11: regen.ecocredit.v1.QueryProjectsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 12: regen.ecocredit.v1.QueryProjectsByClassRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 11: regen.ecocredit.v1.QueryProjectsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 12: regen.ecocredit.v1.QueryProjectsByClassRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 45, // 13: regen.ecocredit.v1.QueryProjectsByClassResponse.projects:type_name -> regen.ecocredit.v1.ProjectInfo - 61, // 14: regen.ecocredit.v1.QueryProjectsByClassResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 15: regen.ecocredit.v1.QueryProjectsByReferenceIdRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 14: regen.ecocredit.v1.QueryProjectsByClassResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 15: regen.ecocredit.v1.QueryProjectsByReferenceIdRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 45, // 16: regen.ecocredit.v1.QueryProjectsByReferenceIdResponse.projects:type_name -> regen.ecocredit.v1.ProjectInfo - 61, // 17: regen.ecocredit.v1.QueryProjectsByReferenceIdResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 18: regen.ecocredit.v1.QueryProjectsByAdminRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 17: regen.ecocredit.v1.QueryProjectsByReferenceIdResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 18: regen.ecocredit.v1.QueryProjectsByAdminRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 45, // 19: regen.ecocredit.v1.QueryProjectsByAdminResponse.projects:type_name -> regen.ecocredit.v1.ProjectInfo - 61, // 20: regen.ecocredit.v1.QueryProjectsByAdminResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 62, // 20: regen.ecocredit.v1.QueryProjectsByAdminResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse 45, // 21: regen.ecocredit.v1.QueryProjectResponse.project:type_name -> regen.ecocredit.v1.ProjectInfo - 60, // 22: regen.ecocredit.v1.QueryBatchesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 61, // 22: regen.ecocredit.v1.QueryBatchesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 46, // 23: regen.ecocredit.v1.QueryBatchesResponse.batches:type_name -> regen.ecocredit.v1.BatchInfo - 61, // 24: regen.ecocredit.v1.QueryBatchesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 25: regen.ecocredit.v1.QueryBatchesByIssuerRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 24: regen.ecocredit.v1.QueryBatchesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 25: regen.ecocredit.v1.QueryBatchesByIssuerRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 46, // 26: regen.ecocredit.v1.QueryBatchesByIssuerResponse.batches:type_name -> regen.ecocredit.v1.BatchInfo - 61, // 27: regen.ecocredit.v1.QueryBatchesByIssuerResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 28: regen.ecocredit.v1.QueryBatchesByClassRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest - 60, // 29: regen.ecocredit.v1.QueryBatchesByProjectRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 27: regen.ecocredit.v1.QueryBatchesByIssuerResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 28: regen.ecocredit.v1.QueryBatchesByClassRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 61, // 29: regen.ecocredit.v1.QueryBatchesByProjectRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 46, // 30: regen.ecocredit.v1.QueryBatchesByProjectResponse.batches:type_name -> regen.ecocredit.v1.BatchInfo - 61, // 31: regen.ecocredit.v1.QueryBatchesByProjectResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 62, // 31: regen.ecocredit.v1.QueryBatchesByProjectResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse 46, // 32: regen.ecocredit.v1.QueryBatchesByClassResponse.batches:type_name -> regen.ecocredit.v1.BatchInfo - 61, // 33: regen.ecocredit.v1.QueryBatchesByClassResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 62, // 33: regen.ecocredit.v1.QueryBatchesByClassResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse 46, // 34: regen.ecocredit.v1.QueryBatchResponse.batch:type_name -> regen.ecocredit.v1.BatchInfo 47, // 35: regen.ecocredit.v1.QueryBalanceResponse.balance:type_name -> regen.ecocredit.v1.BatchBalanceInfo - 60, // 36: regen.ecocredit.v1.QueryBalancesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 61, // 36: regen.ecocredit.v1.QueryBalancesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 47, // 37: regen.ecocredit.v1.QueryBalancesResponse.balances:type_name -> regen.ecocredit.v1.BatchBalanceInfo - 61, // 38: regen.ecocredit.v1.QueryBalancesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 39: regen.ecocredit.v1.QueryBalancesByBatchRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 38: regen.ecocredit.v1.QueryBalancesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 39: regen.ecocredit.v1.QueryBalancesByBatchRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 47, // 40: regen.ecocredit.v1.QueryBalancesByBatchResponse.balances:type_name -> regen.ecocredit.v1.BatchBalanceInfo - 61, // 41: regen.ecocredit.v1.QueryBalancesByBatchResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 60, // 42: regen.ecocredit.v1.QueryAllBalancesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 41: regen.ecocredit.v1.QueryBalancesByBatchResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 61, // 42: regen.ecocredit.v1.QueryAllBalancesRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest 47, // 43: regen.ecocredit.v1.QueryAllBalancesResponse.balances:type_name -> regen.ecocredit.v1.BatchBalanceInfo - 61, // 44: regen.ecocredit.v1.QueryAllBalancesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 62, // 45: regen.ecocredit.v1.QueryCreditTypesResponse.credit_types:type_name -> regen.ecocredit.v1.CreditType - 63, // 46: regen.ecocredit.v1.QueryParamsResponse.params:type_name -> regen.ecocredit.v1.Params - 62, // 47: regen.ecocredit.v1.QueryCreditTypeResponse.credit_type:type_name -> regen.ecocredit.v1.CreditType - 64, // 48: regen.ecocredit.v1.BatchInfo.start_date:type_name -> google.protobuf.Timestamp - 64, // 49: regen.ecocredit.v1.BatchInfo.end_date:type_name -> google.protobuf.Timestamp - 64, // 50: regen.ecocredit.v1.BatchInfo.issuance_date:type_name -> google.protobuf.Timestamp - 60, // 51: regen.ecocredit.v1.QueryAllowedClassCreatorsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest - 61, // 52: regen.ecocredit.v1.QueryAllowedClassCreatorsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 65, // 53: regen.ecocredit.v1.QueryClassFeeResponse.fee:type_name -> cosmos.base.v1beta1.Coin - 66, // 54: regen.ecocredit.v1.QueryProjectEnrollmentResponse.project_class:type_name -> regen.ecocredit.v1.ProjectEnrollment - 60, // 55: regen.ecocredit.v1.QueryProjectEnrollmentsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest - 66, // 56: regen.ecocredit.v1.QueryProjectEnrollmentsResponse.enrollments:type_name -> regen.ecocredit.v1.ProjectEnrollment - 61, // 57: regen.ecocredit.v1.QueryProjectEnrollmentsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 0, // 58: regen.ecocredit.v1.Query.Classes:input_type -> regen.ecocredit.v1.QueryClassesRequest - 2, // 59: regen.ecocredit.v1.Query.ClassesByAdmin:input_type -> regen.ecocredit.v1.QueryClassesByAdminRequest - 4, // 60: regen.ecocredit.v1.Query.Class:input_type -> regen.ecocredit.v1.QueryClassRequest - 6, // 61: regen.ecocredit.v1.Query.ClassIssuers:input_type -> regen.ecocredit.v1.QueryClassIssuersRequest - 8, // 62: regen.ecocredit.v1.Query.Projects:input_type -> regen.ecocredit.v1.QueryProjectsRequest - 10, // 63: regen.ecocredit.v1.Query.ProjectsByClass:input_type -> regen.ecocredit.v1.QueryProjectsByClassRequest - 12, // 64: regen.ecocredit.v1.Query.ProjectsByReferenceId:input_type -> regen.ecocredit.v1.QueryProjectsByReferenceIdRequest - 14, // 65: regen.ecocredit.v1.Query.ProjectsByAdmin:input_type -> regen.ecocredit.v1.QueryProjectsByAdminRequest - 16, // 66: regen.ecocredit.v1.Query.Project:input_type -> regen.ecocredit.v1.QueryProjectRequest - 18, // 67: regen.ecocredit.v1.Query.Batches:input_type -> regen.ecocredit.v1.QueryBatchesRequest - 20, // 68: regen.ecocredit.v1.Query.BatchesByIssuer:input_type -> regen.ecocredit.v1.QueryBatchesByIssuerRequest - 22, // 69: regen.ecocredit.v1.Query.BatchesByClass:input_type -> regen.ecocredit.v1.QueryBatchesByClassRequest - 23, // 70: regen.ecocredit.v1.Query.BatchesByProject:input_type -> regen.ecocredit.v1.QueryBatchesByProjectRequest - 26, // 71: regen.ecocredit.v1.Query.Batch:input_type -> regen.ecocredit.v1.QueryBatchRequest - 28, // 72: regen.ecocredit.v1.Query.Balance:input_type -> regen.ecocredit.v1.QueryBalanceRequest - 30, // 73: regen.ecocredit.v1.Query.Balances:input_type -> regen.ecocredit.v1.QueryBalancesRequest - 32, // 74: regen.ecocredit.v1.Query.BalancesByBatch:input_type -> regen.ecocredit.v1.QueryBalancesByBatchRequest - 34, // 75: regen.ecocredit.v1.Query.AllBalances:input_type -> regen.ecocredit.v1.QueryAllBalancesRequest - 36, // 76: regen.ecocredit.v1.Query.Supply:input_type -> regen.ecocredit.v1.QuerySupplyRequest - 38, // 77: regen.ecocredit.v1.Query.CreditTypes:input_type -> regen.ecocredit.v1.QueryCreditTypesRequest - 40, // 78: regen.ecocredit.v1.Query.Params:input_type -> regen.ecocredit.v1.QueryParamsRequest - 42, // 79: regen.ecocredit.v1.Query.CreditType:input_type -> regen.ecocredit.v1.QueryCreditTypeRequest - 48, // 80: regen.ecocredit.v1.Query.ClassCreatorAllowlist:input_type -> regen.ecocredit.v1.QueryClassCreatorAllowlistRequest - 50, // 81: regen.ecocredit.v1.Query.AllowedClassCreators:input_type -> regen.ecocredit.v1.QueryAllowedClassCreatorsRequest - 52, // 82: regen.ecocredit.v1.Query.ClassFee:input_type -> regen.ecocredit.v1.QueryClassFeeRequest - 54, // 83: regen.ecocredit.v1.Query.AllowedBridgeChains:input_type -> regen.ecocredit.v1.QueryAllowedBridgeChainsRequest - 56, // 84: regen.ecocredit.v1.Query.ProjectEnrollment:input_type -> regen.ecocredit.v1.QueryProjectEnrollmentRequest - 58, // 85: regen.ecocredit.v1.Query.ProjectEnrollments:input_type -> regen.ecocredit.v1.QueryProjectEnrollmentsRequest - 1, // 86: regen.ecocredit.v1.Query.Classes:output_type -> regen.ecocredit.v1.QueryClassesResponse - 3, // 87: regen.ecocredit.v1.Query.ClassesByAdmin:output_type -> regen.ecocredit.v1.QueryClassesByAdminResponse - 5, // 88: regen.ecocredit.v1.Query.Class:output_type -> regen.ecocredit.v1.QueryClassResponse - 7, // 89: regen.ecocredit.v1.Query.ClassIssuers:output_type -> regen.ecocredit.v1.QueryClassIssuersResponse - 9, // 90: regen.ecocredit.v1.Query.Projects:output_type -> regen.ecocredit.v1.QueryProjectsResponse - 11, // 91: regen.ecocredit.v1.Query.ProjectsByClass:output_type -> regen.ecocredit.v1.QueryProjectsByClassResponse - 13, // 92: regen.ecocredit.v1.Query.ProjectsByReferenceId:output_type -> regen.ecocredit.v1.QueryProjectsByReferenceIdResponse - 15, // 93: regen.ecocredit.v1.Query.ProjectsByAdmin:output_type -> regen.ecocredit.v1.QueryProjectsByAdminResponse - 17, // 94: regen.ecocredit.v1.Query.Project:output_type -> regen.ecocredit.v1.QueryProjectResponse - 19, // 95: regen.ecocredit.v1.Query.Batches:output_type -> regen.ecocredit.v1.QueryBatchesResponse - 21, // 96: regen.ecocredit.v1.Query.BatchesByIssuer:output_type -> regen.ecocredit.v1.QueryBatchesByIssuerResponse - 25, // 97: regen.ecocredit.v1.Query.BatchesByClass:output_type -> regen.ecocredit.v1.QueryBatchesByClassResponse - 24, // 98: regen.ecocredit.v1.Query.BatchesByProject:output_type -> regen.ecocredit.v1.QueryBatchesByProjectResponse - 27, // 99: regen.ecocredit.v1.Query.Batch:output_type -> regen.ecocredit.v1.QueryBatchResponse - 29, // 100: regen.ecocredit.v1.Query.Balance:output_type -> regen.ecocredit.v1.QueryBalanceResponse - 31, // 101: regen.ecocredit.v1.Query.Balances:output_type -> regen.ecocredit.v1.QueryBalancesResponse - 33, // 102: regen.ecocredit.v1.Query.BalancesByBatch:output_type -> regen.ecocredit.v1.QueryBalancesByBatchResponse - 35, // 103: regen.ecocredit.v1.Query.AllBalances:output_type -> regen.ecocredit.v1.QueryAllBalancesResponse - 37, // 104: regen.ecocredit.v1.Query.Supply:output_type -> regen.ecocredit.v1.QuerySupplyResponse - 39, // 105: regen.ecocredit.v1.Query.CreditTypes:output_type -> regen.ecocredit.v1.QueryCreditTypesResponse - 41, // 106: regen.ecocredit.v1.Query.Params:output_type -> regen.ecocredit.v1.QueryParamsResponse - 43, // 107: regen.ecocredit.v1.Query.CreditType:output_type -> regen.ecocredit.v1.QueryCreditTypeResponse - 49, // 108: regen.ecocredit.v1.Query.ClassCreatorAllowlist:output_type -> regen.ecocredit.v1.QueryClassCreatorAllowlistResponse - 51, // 109: regen.ecocredit.v1.Query.AllowedClassCreators:output_type -> regen.ecocredit.v1.QueryAllowedClassCreatorsResponse - 53, // 110: regen.ecocredit.v1.Query.ClassFee:output_type -> regen.ecocredit.v1.QueryClassFeeResponse - 55, // 111: regen.ecocredit.v1.Query.AllowedBridgeChains:output_type -> regen.ecocredit.v1.QueryAllowedBridgeChainsResponse - 57, // 112: regen.ecocredit.v1.Query.ProjectEnrollment:output_type -> regen.ecocredit.v1.QueryProjectEnrollmentResponse - 59, // 113: regen.ecocredit.v1.Query.ProjectEnrollments:output_type -> regen.ecocredit.v1.QueryProjectEnrollmentsResponse - 86, // [86:114] is the sub-list for method output_type - 58, // [58:86] is the sub-list for method input_type - 58, // [58:58] is the sub-list for extension type_name - 58, // [58:58] is the sub-list for extension extendee - 0, // [0:58] is the sub-list for field type_name + 62, // 44: regen.ecocredit.v1.QueryAllBalancesResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 63, // 45: regen.ecocredit.v1.QueryCreditTypesResponse.credit_types:type_name -> regen.ecocredit.v1.CreditType + 64, // 46: regen.ecocredit.v1.QueryParamsResponse.params:type_name -> regen.ecocredit.v1.Params + 63, // 47: regen.ecocredit.v1.QueryCreditTypeResponse.credit_type:type_name -> regen.ecocredit.v1.CreditType + 65, // 48: regen.ecocredit.v1.BatchInfo.start_date:type_name -> google.protobuf.Timestamp + 65, // 49: regen.ecocredit.v1.BatchInfo.end_date:type_name -> google.protobuf.Timestamp + 65, // 50: regen.ecocredit.v1.BatchInfo.issuance_date:type_name -> google.protobuf.Timestamp + 61, // 51: regen.ecocredit.v1.QueryAllowedClassCreatorsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 62, // 52: regen.ecocredit.v1.QueryAllowedClassCreatorsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 66, // 53: regen.ecocredit.v1.QueryClassFeeResponse.fee:type_name -> cosmos.base.v1beta1.Coin + 60, // 54: regen.ecocredit.v1.QueryProjectEnrollmentResponse.enrollment:type_name -> regen.ecocredit.v1.EnrollmentInfo + 61, // 55: regen.ecocredit.v1.QueryProjectEnrollmentsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 60, // 56: regen.ecocredit.v1.QueryProjectEnrollmentsResponse.enrollments:type_name -> regen.ecocredit.v1.EnrollmentInfo + 62, // 57: regen.ecocredit.v1.QueryProjectEnrollmentsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 67, // 58: regen.ecocredit.v1.EnrollmentInfo.status:type_name -> regen.ecocredit.v1.ProjectEnrollmentStatus + 0, // 59: regen.ecocredit.v1.Query.Classes:input_type -> regen.ecocredit.v1.QueryClassesRequest + 2, // 60: regen.ecocredit.v1.Query.ClassesByAdmin:input_type -> regen.ecocredit.v1.QueryClassesByAdminRequest + 4, // 61: regen.ecocredit.v1.Query.Class:input_type -> regen.ecocredit.v1.QueryClassRequest + 6, // 62: regen.ecocredit.v1.Query.ClassIssuers:input_type -> regen.ecocredit.v1.QueryClassIssuersRequest + 8, // 63: regen.ecocredit.v1.Query.Projects:input_type -> regen.ecocredit.v1.QueryProjectsRequest + 10, // 64: regen.ecocredit.v1.Query.ProjectsByClass:input_type -> regen.ecocredit.v1.QueryProjectsByClassRequest + 12, // 65: regen.ecocredit.v1.Query.ProjectsByReferenceId:input_type -> regen.ecocredit.v1.QueryProjectsByReferenceIdRequest + 14, // 66: regen.ecocredit.v1.Query.ProjectsByAdmin:input_type -> regen.ecocredit.v1.QueryProjectsByAdminRequest + 16, // 67: regen.ecocredit.v1.Query.Project:input_type -> regen.ecocredit.v1.QueryProjectRequest + 18, // 68: regen.ecocredit.v1.Query.Batches:input_type -> regen.ecocredit.v1.QueryBatchesRequest + 20, // 69: regen.ecocredit.v1.Query.BatchesByIssuer:input_type -> regen.ecocredit.v1.QueryBatchesByIssuerRequest + 22, // 70: regen.ecocredit.v1.Query.BatchesByClass:input_type -> regen.ecocredit.v1.QueryBatchesByClassRequest + 23, // 71: regen.ecocredit.v1.Query.BatchesByProject:input_type -> regen.ecocredit.v1.QueryBatchesByProjectRequest + 26, // 72: regen.ecocredit.v1.Query.Batch:input_type -> regen.ecocredit.v1.QueryBatchRequest + 28, // 73: regen.ecocredit.v1.Query.Balance:input_type -> regen.ecocredit.v1.QueryBalanceRequest + 30, // 74: regen.ecocredit.v1.Query.Balances:input_type -> regen.ecocredit.v1.QueryBalancesRequest + 32, // 75: regen.ecocredit.v1.Query.BalancesByBatch:input_type -> regen.ecocredit.v1.QueryBalancesByBatchRequest + 34, // 76: regen.ecocredit.v1.Query.AllBalances:input_type -> regen.ecocredit.v1.QueryAllBalancesRequest + 36, // 77: regen.ecocredit.v1.Query.Supply:input_type -> regen.ecocredit.v1.QuerySupplyRequest + 38, // 78: regen.ecocredit.v1.Query.CreditTypes:input_type -> regen.ecocredit.v1.QueryCreditTypesRequest + 40, // 79: regen.ecocredit.v1.Query.Params:input_type -> regen.ecocredit.v1.QueryParamsRequest + 42, // 80: regen.ecocredit.v1.Query.CreditType:input_type -> regen.ecocredit.v1.QueryCreditTypeRequest + 48, // 81: regen.ecocredit.v1.Query.ClassCreatorAllowlist:input_type -> regen.ecocredit.v1.QueryClassCreatorAllowlistRequest + 50, // 82: regen.ecocredit.v1.Query.AllowedClassCreators:input_type -> regen.ecocredit.v1.QueryAllowedClassCreatorsRequest + 52, // 83: regen.ecocredit.v1.Query.ClassFee:input_type -> regen.ecocredit.v1.QueryClassFeeRequest + 54, // 84: regen.ecocredit.v1.Query.AllowedBridgeChains:input_type -> regen.ecocredit.v1.QueryAllowedBridgeChainsRequest + 56, // 85: regen.ecocredit.v1.Query.ProjectEnrollment:input_type -> regen.ecocredit.v1.QueryProjectEnrollmentRequest + 58, // 86: regen.ecocredit.v1.Query.ProjectEnrollments:input_type -> regen.ecocredit.v1.QueryProjectEnrollmentsRequest + 1, // 87: regen.ecocredit.v1.Query.Classes:output_type -> regen.ecocredit.v1.QueryClassesResponse + 3, // 88: regen.ecocredit.v1.Query.ClassesByAdmin:output_type -> regen.ecocredit.v1.QueryClassesByAdminResponse + 5, // 89: regen.ecocredit.v1.Query.Class:output_type -> regen.ecocredit.v1.QueryClassResponse + 7, // 90: regen.ecocredit.v1.Query.ClassIssuers:output_type -> regen.ecocredit.v1.QueryClassIssuersResponse + 9, // 91: regen.ecocredit.v1.Query.Projects:output_type -> regen.ecocredit.v1.QueryProjectsResponse + 11, // 92: regen.ecocredit.v1.Query.ProjectsByClass:output_type -> regen.ecocredit.v1.QueryProjectsByClassResponse + 13, // 93: regen.ecocredit.v1.Query.ProjectsByReferenceId:output_type -> regen.ecocredit.v1.QueryProjectsByReferenceIdResponse + 15, // 94: regen.ecocredit.v1.Query.ProjectsByAdmin:output_type -> regen.ecocredit.v1.QueryProjectsByAdminResponse + 17, // 95: regen.ecocredit.v1.Query.Project:output_type -> regen.ecocredit.v1.QueryProjectResponse + 19, // 96: regen.ecocredit.v1.Query.Batches:output_type -> regen.ecocredit.v1.QueryBatchesResponse + 21, // 97: regen.ecocredit.v1.Query.BatchesByIssuer:output_type -> regen.ecocredit.v1.QueryBatchesByIssuerResponse + 25, // 98: regen.ecocredit.v1.Query.BatchesByClass:output_type -> regen.ecocredit.v1.QueryBatchesByClassResponse + 24, // 99: regen.ecocredit.v1.Query.BatchesByProject:output_type -> regen.ecocredit.v1.QueryBatchesByProjectResponse + 27, // 100: regen.ecocredit.v1.Query.Batch:output_type -> regen.ecocredit.v1.QueryBatchResponse + 29, // 101: regen.ecocredit.v1.Query.Balance:output_type -> regen.ecocredit.v1.QueryBalanceResponse + 31, // 102: regen.ecocredit.v1.Query.Balances:output_type -> regen.ecocredit.v1.QueryBalancesResponse + 33, // 103: regen.ecocredit.v1.Query.BalancesByBatch:output_type -> regen.ecocredit.v1.QueryBalancesByBatchResponse + 35, // 104: regen.ecocredit.v1.Query.AllBalances:output_type -> regen.ecocredit.v1.QueryAllBalancesResponse + 37, // 105: regen.ecocredit.v1.Query.Supply:output_type -> regen.ecocredit.v1.QuerySupplyResponse + 39, // 106: regen.ecocredit.v1.Query.CreditTypes:output_type -> regen.ecocredit.v1.QueryCreditTypesResponse + 41, // 107: regen.ecocredit.v1.Query.Params:output_type -> regen.ecocredit.v1.QueryParamsResponse + 43, // 108: regen.ecocredit.v1.Query.CreditType:output_type -> regen.ecocredit.v1.QueryCreditTypeResponse + 49, // 109: regen.ecocredit.v1.Query.ClassCreatorAllowlist:output_type -> regen.ecocredit.v1.QueryClassCreatorAllowlistResponse + 51, // 110: regen.ecocredit.v1.Query.AllowedClassCreators:output_type -> regen.ecocredit.v1.QueryAllowedClassCreatorsResponse + 53, // 111: regen.ecocredit.v1.Query.ClassFee:output_type -> regen.ecocredit.v1.QueryClassFeeResponse + 55, // 112: regen.ecocredit.v1.Query.AllowedBridgeChains:output_type -> regen.ecocredit.v1.QueryAllowedBridgeChainsResponse + 57, // 113: regen.ecocredit.v1.Query.ProjectEnrollment:output_type -> regen.ecocredit.v1.QueryProjectEnrollmentResponse + 59, // 114: regen.ecocredit.v1.Query.ProjectEnrollments:output_type -> regen.ecocredit.v1.QueryProjectEnrollmentsResponse + 87, // [87:115] is the sub-list for method output_type + 59, // [59:87] is the sub-list for method input_type + 59, // [59:59] is the sub-list for extension type_name + 59, // [59:59] is the sub-list for extension extendee + 0, // [0:59] is the sub-list for field type_name } func init() { file_regen_ecocredit_v1_query_proto_init() } @@ -34452,6 +35282,18 @@ func file_regen_ecocredit_v1_query_proto_init() { return nil } } + file_regen_ecocredit_v1_query_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnrollmentInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -34459,7 +35301,7 @@ func file_regen_ecocredit_v1_query_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_regen_ecocredit_v1_query_proto_rawDesc, NumEnums: 0, - NumMessages: 60, + NumMessages: 61, NumExtensions: 0, NumServices: 1, }, diff --git a/api/regen/ecocredit/v1/query_grpc.pb.go b/api/regen/ecocredit/v1/query_grpc.pb.go index 7fd63f21ad..ad2056d64f 100644 --- a/api/regen/ecocredit/v1/query_grpc.pb.go +++ b/api/regen/ecocredit/v1/query_grpc.pb.go @@ -135,8 +135,8 @@ type QueryClient interface { // // Since Revision 3 ProjectEnrollment(ctx context.Context, in *QueryProjectEnrollmentRequest, opts ...grpc.CallOption) (*QueryProjectEnrollmentResponse, error) - // ProjectEnrollments queries all credit class enrollments associated with a - // project. + // ProjectEnrollments queries all credit class enrollments and allows for filtering by + // project or credit class. ProjectEnrollments(ctx context.Context, in *QueryProjectEnrollmentsRequest, opts ...grpc.CallOption) (*QueryProjectEnrollmentsResponse, error) } @@ -487,8 +487,8 @@ type QueryServer interface { // // Since Revision 3 ProjectEnrollment(context.Context, *QueryProjectEnrollmentRequest) (*QueryProjectEnrollmentResponse, error) - // ProjectEnrollments queries all credit class enrollments associated with a - // project. + // ProjectEnrollments queries all credit class enrollments and allows for filtering by + // project or credit class. ProjectEnrollments(context.Context, *QueryProjectEnrollmentsRequest) (*QueryProjectEnrollmentsResponse, error) mustEmbedUnimplementedQueryServer() } diff --git a/api/regen/ecocredit/v1/state.pulsar.go b/api/regen/ecocredit/v1/state.pulsar.go index 3ea1cfdc2a..6eed0c247b 100644 --- a/api/regen/ecocredit/v1/state.pulsar.go +++ b/api/regen/ecocredit/v1/state.pulsar.go @@ -10024,6 +10024,8 @@ type CreditType struct { // abbreviation is a 1-3 character uppercase abbreviation of the CreditType // name, used in batch denominations within the CreditType. It must be unique. + // The letter P is reserved as the project prefix and cannot be used as a + // credit type to avoid confusion. Abbreviation string `protobuf:"bytes,1,opt,name=abbreviation,proto3" json:"abbreviation,omitempty"` // name is the name of the credit type (e.g. carbon, biodiversity). Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` @@ -10213,13 +10215,13 @@ type Project struct { // key is the table row identifier of the project used internally for // efficient lookups. This identifier is auto-incrementing. Key uint64 `protobuf:"varint,1,opt,name=key,proto3" json:"key,omitempty"` - // id is the unique identifier of the project either auto-generated from the - // credit class id and project sequence number or provided upon creation. + // id is the auto-generated unique identifier of the project. Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` // admin is the admin of the project. Admin []byte `protobuf:"bytes,3,opt,name=admin,proto3" json:"admin,omitempty"` - // class_key is the table row identifier of the credit class used internally - // for efficient lookups. This links a project to a credit class. + // Deprecated: use ProjectEnrollment instead. + // + // Deprecated: Do not use. ClassKey uint64 `protobuf:"varint,4,opt,name=class_key,json=classKey,proto3" json:"class_key,omitempty"` // jurisdiction is the jurisdiction of the project. // Full documentation can be found in MsgCreateProject.jurisdiction. @@ -10271,6 +10273,7 @@ func (x *Project) GetAdmin() []byte { return nil } +// Deprecated: Do not use. func (x *Project) GetClassKey() uint64 { if x != nil { return x.ClassKey @@ -10476,8 +10479,9 @@ func (x *ClassSequence) GetNextSequence() uint64 { return 0 } -// ProjectSequence stores and increments the sequence number for projects within -// a credit class. +// Deprecated: No longer used. +// +// Deprecated: Do not use. type ProjectSequence struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -11177,191 +11181,191 @@ var file_regen_ecocredit_v1_state_proto_rawDesc = []byte{ 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x1c, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x16, 0x0a, 0x12, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, - 0x65, 0x79, 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x03, 0x22, 0xab, 0x02, 0x0a, 0x07, + 0x65, 0x79, 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x03, 0x22, 0xaf, 0x02, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, - 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, - 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x3a, - 0x68, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x62, 0x0a, 0x07, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x10, 0x01, - 0x12, 0x08, 0x0a, 0x02, 0x69, 0x64, 0x10, 0x01, 0x18, 0x01, 0x12, 0x12, 0x0a, 0x0c, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x69, 0x64, 0x10, 0x02, 0x18, 0x01, 0x12, 0x09, - 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x10, 0x05, 0x18, 0x04, 0x22, 0xc4, 0x03, 0x0a, 0x05, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1f, 0x0a, - 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, - 0x65, 0x6e, 0x6f, 0x6d, 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, - 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x65, - 0x6e, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x1f, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, + 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x49, 0x64, 0x3a, 0x68, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x62, 0x0a, 0x07, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x02, 0x69, 0x64, 0x10, 0x01, 0x18, 0x01, 0x12, 0x12, + 0x0a, 0x0c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x69, 0x64, 0x10, 0x02, + 0x18, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x10, 0x03, 0x12, 0x10, 0x0a, + 0x0c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x10, 0x04, 0x12, + 0x1a, 0x0a, 0x16, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x10, 0x05, 0x18, 0x04, 0x22, 0xc4, 0x03, + 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, + 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 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, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, + 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, + 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, + 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x44, 0x61, - 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x64, - 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x44, - 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x4b, 0x65, 0x79, 0x3a, 0x5a, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x54, 0x0a, 0x07, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x10, 0x01, - 0x18, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, - 0x79, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, - 0x65, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, 0x04, 0x12, - 0x0d, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x10, 0x05, 0x18, 0x05, - 0x22, 0x82, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x5f, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x41, 0x62, 0x62, 0x72, 0x65, 0x76, - 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x71, - 0x75, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x1e, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x18, 0x0a, 0x14, 0x0a, - 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x62, 0x62, - 0x72, 0x65, 0x76, 0x18, 0x06, 0x22, 0x6a, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x65, - 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6e, 0x65, - 0x78, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x15, 0xf2, 0x9e, 0xd3, 0x8e, - 0x03, 0x0f, 0x0a, 0x0b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x07, 0x22, 0x6e, 0x0a, 0x0d, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, - 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x17, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x11, - 0x0a, 0x0d, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x08, 0x22, 0xf4, 0x01, 0x0a, 0x0c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4b, 0x65, 0x79, 0x12, - 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, - 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x69, - 0x72, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x73, 0x63, - 0x72, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x3a, 0x34, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x2e, 0x0a, 0x13, 0x0a, 0x11, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x2c, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x12, - 0x15, 0x0a, 0x11, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x18, 0x09, 0x22, 0xbc, 0x01, 0x0a, 0x0b, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x69, 0x73, 0x73, 0x75, 0x61, + 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x3a, 0x5a, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x54, + 0x0a, 0x07, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x05, 0x64, 0x65, 0x6e, + 0x6f, 0x6d, 0x10, 0x01, 0x18, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x72, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, + 0x10, 0x05, 0x18, 0x05, 0x22, 0x82, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x53, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x41, 0x62, + 0x62, 0x72, 0x65, 0x76, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6e, 0x65, 0x78, + 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x1e, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, + 0x18, 0x0a, 0x14, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x18, 0x06, 0x22, 0x6c, 0x0a, 0x0f, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x17, + 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x0f, 0x0a, 0x0b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x07, 0x18, 0x01, 0x22, 0x6e, 0x0a, 0x0d, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x17, + 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x11, 0x0a, 0x0d, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x22, 0xf4, 0x01, 0x0a, 0x0c, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x61, 0x74, - 0x63, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, - 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, - 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x41, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, - 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x3a, 0x15, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x0f, 0x0a, 0x0b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, - 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x22, 0x75, 0x0a, 0x0d, 0x4f, 0x72, 0x69, 0x67, 0x69, - 0x6e, 0x54, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x1f, 0xf2, - 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x15, 0x0a, 0x13, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, - 0x65, 0x79, 0x2c, 0x69, 0x64, 0x2c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0b, 0x22, 0x96, - 0x01, 0x0a, 0x0d, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, - 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x3a, 0x2f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x29, 0x0a, 0x0b, - 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x12, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x74, 0x10, 0x01, 0x18, 0x01, 0x18, 0x0c, 0x22, 0x3b, 0x0a, 0x15, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x08, 0xfa, 0x9e, 0xd3, 0x8e, - 0x03, 0x02, 0x08, 0x0d, 0x22, 0x44, 0x0a, 0x13, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x13, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x0d, 0x0a, 0x09, 0x0a, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0e, 0x22, 0x41, 0x0a, 0x08, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x12, 0x2b, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x01, 0x20, - 0x01, 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, 0x52, 0x03, - 0x66, 0x65, 0x65, 0x3a, 0x08, 0xfa, 0x9e, 0xd3, 0x8e, 0x03, 0x02, 0x08, 0x0f, 0x22, 0x4b, 0x0a, - 0x12, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4e, 0x61, - 0x6d, 0x65, 0x3a, 0x16, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x10, 0x0a, 0x0c, 0x0a, 0x0a, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x22, 0xac, 0x02, 0x0a, 0x11, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, - 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x43, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, - 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x13, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x12, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x30, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x2a, 0x0a, - 0x17, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x12, 0x0d, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x10, 0x01, 0x18, 0x11, 0x22, 0x43, 0x0a, 0x0a, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, 0x12, 0x2b, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x01, - 0x20, 0x01, 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, 0x52, - 0x03, 0x66, 0x65, 0x65, 0x3a, 0x08, 0xfa, 0x9e, 0xd3, 0x8e, 0x03, 0x02, 0x08, 0x12, 0x2a, 0xef, - 0x01, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x25, 0x50, 0x52, - 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, - 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x2f, 0x0a, - 0x2b, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, - 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, - 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x26, - 0x0a, 0x22, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, - 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, - 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x28, 0x0a, 0x24, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, - 0x54, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x04, - 0x42, 0xd8, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x45, 0x58, 0xaa, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, - 0x6e, 0x2e, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, - 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x3a, 0x3a, 0x45, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x63, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, + 0x6c, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x69, + 0x72, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x27, 0x0a, 0x0f, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x77, + 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x34, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x2e, + 0x0a, 0x13, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2c, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x12, 0x15, 0x0a, 0x11, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, + 0x65, 0x79, 0x2c, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x18, 0x09, 0x22, 0xbc, + 0x01, 0x0a, 0x0b, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x1b, + 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x5f, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, + 0x74, 0x69, 0x72, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, + 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x15, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x0f, 0x0a, 0x0b, + 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x22, 0x75, 0x0a, + 0x0d, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1b, + 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x15, 0x0a, 0x13, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x69, 0x64, 0x2c, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x0b, 0x22, 0x96, 0x01, 0x0a, 0x0d, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x3a, 0x2f, 0xf2, 0x9e, + 0xd3, 0x8e, 0x03, 0x29, 0x0a, 0x0b, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6b, 0x65, + 0x79, 0x12, 0x18, 0x0a, 0x12, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x10, 0x01, 0x18, 0x01, 0x18, 0x0c, 0x22, 0x3b, 0x0a, + 0x15, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, + 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x3a, 0x08, 0xfa, 0x9e, 0xd3, 0x8e, 0x03, 0x02, 0x08, 0x0d, 0x22, 0x44, 0x0a, 0x13, 0x41, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x13, 0xf2, 0x9e, 0xd3, + 0x8e, 0x03, 0x0d, 0x0a, 0x09, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0e, + 0x22, 0x41, 0x0a, 0x08, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x12, 0x2b, 0x0a, 0x03, + 0x66, 0x65, 0x65, 0x18, 0x01, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x08, 0xfa, 0x9e, 0xd3, 0x8e, 0x03, + 0x02, 0x08, 0x0f, 0x22, 0x4b, 0x0a, 0x12, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x16, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x10, + 0x0a, 0x0c, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, + 0x22, 0xac, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x4b, 0x65, 0x79, 0x12, 0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x13, + 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x65, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x30, 0xf2, + 0x9e, 0xd3, 0x8e, 0x03, 0x2a, 0x0a, 0x17, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x6b, 0x65, 0x79, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x12, 0x0d, + 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x10, 0x01, 0x18, 0x11, 0x22, + 0x43, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, 0x12, 0x2b, 0x0a, + 0x03, 0x66, 0x65, 0x65, 0x18, 0x01, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x08, 0xfa, 0x9e, 0xd3, 0x8e, + 0x03, 0x02, 0x08, 0x12, 0x2a, 0xef, 0x01, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x29, 0x0a, 0x25, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x45, 0x4e, 0x52, 0x4f, + 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, 0x22, 0x50, + 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, + 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x2f, 0x0a, 0x2b, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x45, + 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, + 0x45, 0x44, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, + 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x28, 0x0a, 0x24, + 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, + 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, + 0x41, 0x54, 0x45, 0x44, 0x10, 0x04, 0x42, 0xd8, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, + 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, + 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x63, + 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x45, 0x58, 0xaa, + 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x52, 0x65, 0x67, 0x65, + 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x52, 0x65, 0x67, + 0x65, 0x6e, 0x3a, 0x3a, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/regen/ecocredit/v1/tx.pulsar.go b/api/regen/ecocredit/v1/tx.pulsar.go index 253d959159..874edba163 100644 --- a/api/regen/ecocredit/v1/tx.pulsar.go +++ b/api/regen/ecocredit/v1/tx.pulsar.go @@ -3,6 +3,10 @@ package ecocreditv1 import ( fmt "fmt" + io "io" + reflect "reflect" + sync "sync" + runtime "github.com/cosmos/cosmos-proto/runtime" v1beta1 "github.com/cosmos/cosmos-sdk/api/cosmos/base/v1beta1" _ "github.com/cosmos/cosmos-sdk/api/cosmos/msg/v1" @@ -11,9 +15,6 @@ import ( protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - io "io" - reflect "reflect" - sync "sync" ) var ( @@ -3222,7 +3223,6 @@ var ( fd_MsgCreateUnregisteredProject_admin protoreflect.FieldDescriptor fd_MsgCreateUnregisteredProject_metadata protoreflect.FieldDescriptor fd_MsgCreateUnregisteredProject_jurisdiction protoreflect.FieldDescriptor - fd_MsgCreateUnregisteredProject_reference_id protoreflect.FieldDescriptor fd_MsgCreateUnregisteredProject_fee protoreflect.FieldDescriptor ) @@ -3232,7 +3232,6 @@ func init() { fd_MsgCreateUnregisteredProject_admin = md_MsgCreateUnregisteredProject.Fields().ByName("admin") fd_MsgCreateUnregisteredProject_metadata = md_MsgCreateUnregisteredProject.Fields().ByName("metadata") fd_MsgCreateUnregisteredProject_jurisdiction = md_MsgCreateUnregisteredProject.Fields().ByName("jurisdiction") - fd_MsgCreateUnregisteredProject_reference_id = md_MsgCreateUnregisteredProject.Fields().ByName("reference_id") fd_MsgCreateUnregisteredProject_fee = md_MsgCreateUnregisteredProject.Fields().ByName("fee") } @@ -3319,12 +3318,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) Range(f func(protoreflect. return } } - if x.ReferenceId != "" { - value := protoreflect.ValueOfString(x.ReferenceId) - if !f(fd_MsgCreateUnregisteredProject_reference_id, value) { - return - } - } if x.Fee != nil { value := protoreflect.ValueOfMessage(x.Fee.ProtoReflect()) if !f(fd_MsgCreateUnregisteredProject_fee, value) { @@ -3352,8 +3345,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) Has(fd protoreflect.FieldD return x.Metadata != "" case "regen.ecocredit.v1.MsgCreateUnregisteredProject.jurisdiction": return x.Jurisdiction != "" - case "regen.ecocredit.v1.MsgCreateUnregisteredProject.reference_id": - return x.ReferenceId != "" case "regen.ecocredit.v1.MsgCreateUnregisteredProject.fee": return x.Fee != nil default: @@ -3378,8 +3369,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) Clear(fd protoreflect.Fiel x.Metadata = "" case "regen.ecocredit.v1.MsgCreateUnregisteredProject.jurisdiction": x.Jurisdiction = "" - case "regen.ecocredit.v1.MsgCreateUnregisteredProject.reference_id": - x.ReferenceId = "" case "regen.ecocredit.v1.MsgCreateUnregisteredProject.fee": x.Fee = nil default: @@ -3407,9 +3396,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) Get(descriptor protoreflec case "regen.ecocredit.v1.MsgCreateUnregisteredProject.jurisdiction": value := x.Jurisdiction return protoreflect.ValueOfString(value) - case "regen.ecocredit.v1.MsgCreateUnregisteredProject.reference_id": - value := x.ReferenceId - return protoreflect.ValueOfString(value) case "regen.ecocredit.v1.MsgCreateUnregisteredProject.fee": value := x.Fee return protoreflect.ValueOfMessage(value.ProtoReflect()) @@ -3439,8 +3425,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) Set(fd protoreflect.FieldD x.Metadata = value.Interface().(string) case "regen.ecocredit.v1.MsgCreateUnregisteredProject.jurisdiction": x.Jurisdiction = value.Interface().(string) - case "regen.ecocredit.v1.MsgCreateUnregisteredProject.reference_id": - x.ReferenceId = value.Interface().(string) case "regen.ecocredit.v1.MsgCreateUnregisteredProject.fee": x.Fee = value.Message().Interface().(*v1beta1.Coin) default: @@ -3474,8 +3458,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) Mutable(fd protoreflect.Fi panic(fmt.Errorf("field metadata of message regen.ecocredit.v1.MsgCreateUnregisteredProject is not mutable")) case "regen.ecocredit.v1.MsgCreateUnregisteredProject.jurisdiction": panic(fmt.Errorf("field jurisdiction of message regen.ecocredit.v1.MsgCreateUnregisteredProject is not mutable")) - case "regen.ecocredit.v1.MsgCreateUnregisteredProject.reference_id": - panic(fmt.Errorf("field reference_id of message regen.ecocredit.v1.MsgCreateUnregisteredProject is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: regen.ecocredit.v1.MsgCreateUnregisteredProject")) @@ -3495,8 +3477,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) NewField(fd protoreflect.F return protoreflect.ValueOfString("") case "regen.ecocredit.v1.MsgCreateUnregisteredProject.jurisdiction": return protoreflect.ValueOfString("") - case "regen.ecocredit.v1.MsgCreateUnregisteredProject.reference_id": - return protoreflect.ValueOfString("") case "regen.ecocredit.v1.MsgCreateUnregisteredProject.fee": m := new(v1beta1.Coin) return protoreflect.ValueOfMessage(m.ProtoReflect()) @@ -3581,10 +3561,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) ProtoMethods() *protoiface if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - l = len(x.ReferenceId) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } if x.Fee != nil { l = options.Size(x.Fee) n += 1 + l + runtime.Sov(uint64(l)) @@ -3630,13 +3606,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) ProtoMethods() *protoiface copy(dAtA[i:], encoded) i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) i-- - dAtA[i] = 0x2a - } - if len(x.ReferenceId) > 0 { - i -= len(x.ReferenceId) - copy(dAtA[i:], x.ReferenceId) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ReferenceId))) - i-- dAtA[i] = 0x22 } if len(x.Jurisdiction) > 0 { @@ -3806,38 +3775,6 @@ func (x *fastReflection_MsgCreateUnregisteredProject) ProtoMethods() *protoiface x.Jurisdiction = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ReferenceId", 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.ReferenceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Fee", wireType) } @@ -29676,15 +29613,12 @@ type MsgCreateUnregisteredProject struct { // sub-national-code and postal-code are optional and can be added for // increased precision. Jurisdiction string `protobuf:"bytes,3,opt,name=jurisdiction,proto3" json:"jurisdiction,omitempty"` - // reference_id is any arbitrary string used to reference the project with a - // maximum length of 32 characters. - ReferenceId string `protobuf:"bytes,4,opt,name=reference_id,json=referenceId,proto3" json:"reference_id,omitempty"` // fee is the project creation fee. An equal fee is required if the project // creation fee parameter is set. The provided fee can be greater than the // parameter, but only the amount in the parameter will be charged. // // Since Revision 3 - Fee *v1beta1.Coin `protobuf:"bytes,5,opt,name=fee,proto3" json:"fee,omitempty"` + Fee *v1beta1.Coin `protobuf:"bytes,4,opt,name=fee,proto3" json:"fee,omitempty"` } func (x *MsgCreateUnregisteredProject) Reset() { @@ -29728,13 +29662,6 @@ func (x *MsgCreateUnregisteredProject) GetJurisdiction() string { return "" } -func (x *MsgCreateUnregisteredProject) GetReferenceId() string { - if x != nil { - return x.ReferenceId - } - return "" -} - func (x *MsgCreateUnregisteredProject) GetFee() *v1beta1.Coin { if x != nil { return x.Fee @@ -32230,7 +32157,7 @@ var file_regen_ecocredit_v1_tx_proto_rawDesc = []byte{ 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x22, 0xd0, 0x01, 0x0a, 0x1c, 0x4d, 0x73, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x22, 0xad, 0x01, 0x0a, 0x1c, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, @@ -32238,535 +32165,532 @@ var file_regen_ecocredit_v1_tx_proto_rawDesc = []byte{ 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, - 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x45, 0x0a, 0x24, - 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x49, 0x64, 0x22, 0xc9, 0x01, 0x0a, 0x1c, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x1a, 0x0a, 0x08, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x3a, 0x12, 0x82, 0xe7, 0xb0, - 0x2a, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, - 0x26, 0x0a, 0x24, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe3, 0x01, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1d, - 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x4a, 0x0a, 0x0a, 0x6e, 0x65, 0x77, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x72, + 0x12, 0x2b, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x04, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x0a, 0x82, + 0xe7, 0xb0, 0x2a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x45, 0x0a, 0x24, 0x4d, 0x73, 0x67, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, + 0x22, 0xc9, 0x01, 0x0a, 0x1c, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, + 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x3a, 0x12, 0x82, 0xe7, 0xb0, 0x2a, 0x0d, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x26, 0x0a, 0x24, + 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe3, 0x01, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x4a, 0x0a, 0x0a, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, + 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, 0x3a, 0x0b, 0x82, + 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x24, 0x0a, 0x22, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x97, 0x03, 0x0a, 0x0e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x08, 0x69, 0x73, + 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, - 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x6e, 0x65, 0x77, 0x53, 0x74, - 0x61, 0x74, 0x75, 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, - 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x24, 0x0a, - 0x22, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x97, 0x03, 0x0a, 0x0e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1d, - 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x3d, 0x0a, - 0x08, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x21, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x49, 0x73, 0x73, 0x75, 0x61, 0x6e, - 0x63, 0x65, 0x52, 0x08, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x09, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x65, 0x6e, 0x64, - 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x07, 0x65, - 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x6f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x49, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x52, + 0x08, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x61, + 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x44, + 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x5f, 0x74, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x54, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x3a, 0x0b, 0x82, + 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x39, 0x0a, 0x16, 0x4d, 0x73, + 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, + 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x22, 0xd5, 0x01, 0x0a, 0x13, 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x6e, + 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, + 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x3d, 0x0a, 0x08, 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, + 0x63, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x49, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x73, 0x73, + 0x75, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, + 0x74, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, + 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x1d, 0x0a, + 0x1b, 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x0a, 0x0c, + 0x4d, 0x73, 0x67, 0x53, 0x65, 0x61, 0x6c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, + 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, + 0x73, 0x75, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, + 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, + 0x65, 0x72, 0x22, 0x16, 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x61, 0x6c, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf6, 0x02, 0x0a, 0x07, 0x4d, + 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x07, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x52, 0x08, 0x6f, 0x72, 0x69, - 0x67, 0x69, 0x6e, 0x54, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, - 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, - 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x39, 0x0a, - 0x16, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, - 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, - 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x22, 0xd5, 0x01, 0x0a, 0x13, 0x4d, 0x73, 0x67, - 0x4d, 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, - 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x3d, 0x0a, 0x08, 0x69, 0x73, 0x73, - 0x75, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x65, + 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x1a, + 0xe4, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x12, + 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, + 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x64, 0x61, + 0x62, 0x6c, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x74, + 0x69, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x37, 0x0a, 0x17, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6a, + 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x16, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4a, 0x75, 0x72, + 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x74, + 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x22, 0x11, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x09, 0x4d, 0x73, 0x67, 0x52, 0x65, + 0x74, 0x69, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x49, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, - 0x69, 0x73, 0x73, 0x75, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x5f, 0x74, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x65, - 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x69, - 0x6e, 0x54, 0x78, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, - 0x22, 0x1d, 0x0a, 0x1b, 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x54, 0x0a, 0x0c, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x61, 0x6c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, - 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, - 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, - 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, - 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x16, 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x61, 0x6c, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf6, 0x02, - 0x0a, 0x07, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, - 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, - 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, - 0x41, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x2e, 0x53, 0x65, - 0x6e, 0x64, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x73, 0x1a, 0xe4, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, - 0x6e, 0x6f, 0x6d, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, - 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, - 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x64, 0x41, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x17, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x5f, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x4a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, - 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x74, 0x69, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, - 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x22, 0x11, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x09, 0x4d, 0x73, - 0x67, 0x52, 0x65, 0x74, 0x69, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x35, 0x0a, - 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x52, 0x07, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6a, 0x75, 0x72, 0x69, - 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x0a, 0x82, + 0xe7, 0xb0, 0x2a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x13, 0x0a, 0x11, 0x4d, 0x73, 0x67, + 0x52, 0x65, 0x74, 0x69, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, + 0x0a, 0x09, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, + 0x72, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x52, + 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x13, 0x0a, 0x11, - 0x4d, 0x73, 0x67, 0x52, 0x65, 0x74, 0x69, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x7c, 0x0a, 0x09, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x14, - 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, - 0x77, 0x6e, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x73, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, - 0x73, 0x6f, 0x6e, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, - 0x13, 0x0a, 0x11, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6f, 0x0a, 0x13, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, + 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x6f, 0x0a, 0x13, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x77, + 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x65, + 0x77, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x22, 0x1d, 0x0a, 0x1b, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x64, 0x64, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, + 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x73, 0x73, + 0x75, 0x65, 0x72, 0x73, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x22, 0x1f, 0x0a, 0x1d, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x78, 0x0a, 0x16, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6e, 0x65, 0x77, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x1d, 0x0a, 0x1b, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x12, 0x14, - 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, - 0x1f, 0x0a, 0x0b, 0x61, 0x64, 0x64, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, - 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, - 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x78, 0x0a, 0x16, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, - 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x20, - 0x0a, 0x1e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x75, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, - 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, - 0x2a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x4d, 0x73, 0x67, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, - 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x6e, 0x65, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x82, 0xe7, - 0xb0, 0x2a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x22, 0x0a, 0x20, 0x4d, 0x73, 0x67, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x01, 0x0a, - 0x09, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, - 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x63, - 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x73, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x3a, 0x0a, 0x82, - 0xe7, 0xb0, 0x2a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x81, 0x01, 0x0a, 0x16, 0x4d, 0x73, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, + 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x20, 0x0a, 0x1e, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, + 0x15, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e, + 0x65, 0x77, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6e, 0x65, 0x77, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, + 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x22, 0x0a, 0x20, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x4d, 0x73, + 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, + 0x65, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x73, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, + 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x81, 0x01, 0x0a, 0x16, 0x4d, 0x73, 0x67, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, + 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, + 0x77, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0b, 0x82, + 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x20, 0x0a, 0x1e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, - 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x21, 0x0a, - 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x20, 0x0a, - 0x1e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x13, 0x0a, 0x11, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdf, 0x04, 0x0a, 0x10, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, - 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, - 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x46, 0x0a, 0x07, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, - 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, - 0x69, 0x76, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x40, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, - 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x12, 0x39, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, - 0x5f, 0x74, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x65, 0x67, 0x65, - 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, - 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, - 0x78, 0x1a, 0xd7, 0x01, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x72, - 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, - 0x74, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 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, 0x1a, 0x6c, 0x0a, 0x07, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x75, 0x72, - 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, - 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x22, 0x5a, 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, - 0x6e, 0x6f, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x49, 0x64, 0x22, 0x5c, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, - 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x22, 0x1c, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, - 0x0a, 0x1b, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, - 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x25, 0x0a, 0x23, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x74, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, - 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5f, 0x0a, 0x15, - 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x0a, 0x11, + 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xdf, 0x04, 0x0a, 0x10, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, + 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x64, 0x12, 0x46, 0x0a, 0x07, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x40, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, + 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x62, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x39, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x78, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x54, 0x78, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x1a, 0xd7, + 0x01, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x63, + 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, + 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, + 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, + 0x3b, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0x90, + 0xdf, 0x1f, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 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, 0x1a, 0x6c, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x75, 0x72, 0x69, 0x73, 0x64, + 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6a, 0x75, + 0x72, 0x69, 0x73, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x73, 0x73, + 0x75, 0x65, 0x72, 0x22, 0x5a, 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6e, 0x6f, 0x6d, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x22, + 0x5c, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3a, 0x0e, 0x82, - 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x1f, 0x0a, - 0x1d, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6e, - 0x0a, 0x11, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x46, 0x65, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x12, 0x2b, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x0e, - 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x1b, - 0x0a, 0x19, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x0a, 0x13, 0x4d, - 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, - 0x65, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, + 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x1c, 0x0a, + 0x1a, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, 0x0a, 0x1b, 0x4d, + 0x73, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, + 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x22, 0x25, 0x0a, 0x23, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5f, 0x0a, 0x15, 0x4d, 0x73, 0x67, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x12, 0x2b, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x0e, 0x82, - 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x1d, 0x0a, - 0x1b, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x67, 0x0a, 0x18, - 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x22, 0x0a, 0x20, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x41, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x1f, 0x0a, 0x1d, 0x4d, 0x73, + 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6e, 0x0a, 0x11, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2b, + 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, + 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x1b, 0x0a, 0x19, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x0a, 0x13, 0x4d, 0x73, 0x67, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2b, 0x0a, + 0x03, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 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, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x1d, 0x0a, 0x1b, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x67, 0x0a, 0x18, 0x4d, 0x73, 0x67, + 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4e, 0x61, + 0x6d, 0x65, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x22, 0x22, 0x0a, 0x20, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6a, 0x0a, 0x1b, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4e, 0x61, + 0x6d, 0x65, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x22, 0x25, 0x0a, 0x23, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6a, 0x0a, 0x1b, 0x4d, 0x73, 0x67, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x25, 0x0a, 0x23, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x63, 0x0a, 0x0c, - 0x4d, 0x73, 0x67, 0x42, 0x75, 0x72, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, - 0x62, 0x75, 0x72, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, - 0x72, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x62, 0x75, 0x72, 0x6e, 0x65, - 0x72, 0x22, 0x16, 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x42, 0x75, 0x72, 0x6e, 0x52, 0x65, 0x67, 0x65, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe5, 0x17, 0x0a, 0x03, 0x4d, 0x73, - 0x67, 0x12, 0x5d, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x12, 0x22, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x1a, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x63, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x12, 0x24, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0x38, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x87, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x63, 0x0a, 0x0c, 0x4d, 0x73, 0x67, + 0x42, 0x75, 0x72, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x72, + 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x72, 0x6e, 0x65, + 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x62, 0x75, 0x72, 0x6e, 0x65, 0x72, 0x22, 0x16, + 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x42, 0x75, 0x72, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe5, 0x17, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x5d, + 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, - 0x38, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x17, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x36, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, - 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x22, 0x2e, 0x72, + 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x1a, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, + 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x24, + 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x30, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, + 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x1a, 0x38, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, + 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x72, 0x65, 0x67, + 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x38, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x1a, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x10, - 0x4d, 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, - 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x2e, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x1a, 0x36, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0b, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x22, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x4d, 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x09, 0x53, 0x65, - 0x61, 0x6c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x2a, 0x2e, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x10, 0x4d, 0x69, 0x6e, + 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x12, 0x27, 0x2e, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4d, + 0x69, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x09, 0x53, 0x65, 0x61, 0x6c, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x61, + 0x6c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, + 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, + 0x65, 0x61, 0x6c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x48, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1b, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, + 0x67, 0x53, 0x65, 0x6e, 0x64, 0x1a, 0x23, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, + 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, + 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x52, 0x65, + 0x74, 0x69, 0x72, 0x65, 0x12, 0x1d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x74, + 0x69, 0x72, 0x65, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x74, 0x69, + 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x43, 0x61, + 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x1d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, + 0x63, 0x65, 0x6c, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x10, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x27, + 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x53, 0x65, 0x61, 0x6c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x12, 0x29, + 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x1a, 0x31, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x53, 0x65, 0x61, 0x6c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1b, 0x2e, 0x72, 0x65, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, + 0x75, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x13, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, + 0x32, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x29, 0x2e, 0x72, 0x65, 0x67, 0x65, + 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x41, + 0x64, 0x6d, 0x69, 0x6e, 0x1a, 0x31, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x34, + 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x1a, 0x23, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, - 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, - 0x06, 0x52, 0x65, 0x74, 0x69, 0x72, 0x65, 0x12, 0x1d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x52, 0x65, 0x74, 0x69, 0x72, 0x65, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, - 0x65, 0x74, 0x69, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, - 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x1d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x32, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, - 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, - 0x6e, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, - 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x41, 0x64, - 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x12, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, - 0x73, 0x12, 0x29, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x1a, 0x31, 0x2e, 0x72, - 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x75, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x1a, 0x32, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x29, 0x2e, 0x72, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x42, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x1d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, + 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x0d, 0x42, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x12, 0x24, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x1a, 0x31, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x63, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x24, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x72, 0x65, + 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x6d, - 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x15, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x1a, 0x34, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, - 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x32, 0x2e, 0x72, 0x65, 0x67, - 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, - 0x0a, 0x06, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x1d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, - 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x41, 0x64, 0x64, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, 0x69, + 0x73, 0x74, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x74, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x6c, + 0x69, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x74, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, + 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x0f, + 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, + 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x2e, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, - 0x0a, 0x0d, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x12, - 0x24, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, - 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, - 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x2c, 0x2e, 0x72, 0x65, 0x67, - 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x18, 0x53, 0x65, 0x74, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x6f, - 0x77, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, - 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, - 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, - 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, - 0x65, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, - 0x6c, 0x6f, 0x77, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x69, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x6f, 0x72, 0x12, 0x26, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, - 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x2e, 0x2e, 0x72, 0x65, 0x67, - 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x12, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, - 0x12, 0x29, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x31, 0x2e, 0x72, 0x65, - 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, - 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, - 0x12, 0x25, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x1a, 0x2d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, + 0x41, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x29, 0x2e, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x31, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, + 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x0e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x12, 0x25, 0x2e, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x46, 0x65, 0x65, 0x1a, 0x2d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x67, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, + 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x7b, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x2c, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x46, 0x65, 0x65, 0x1a, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, - 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x2c, 0x2e, - 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, - 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x1a, 0x34, 0x2e, 0x72, 0x65, + 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x1a, 0x34, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, + 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, + 0x67, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, + 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x2f, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x84, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x2f, - 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x1a, - 0x37, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, - 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x09, 0x42, 0x75, 0x72, 0x6e, - 0x52, 0x65, 0x67, 0x65, 0x6e, 0x12, 0x20, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, - 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x75, - 0x72, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x42, 0x75, 0x72, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0xd5, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, - 0x69, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x76, - 0x31, 0xa2, 0x02, 0x03, 0x52, 0x45, 0x58, 0xaa, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x2e, - 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x52, - 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, - 0x31, 0xe2, 0x02, 0x1e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, - 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x14, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x3a, 0x3a, 0x45, 0x63, 0x6f, 0x63, - 0x72, 0x65, 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x1a, 0x37, 0x2e, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x09, 0x42, 0x75, 0x72, 0x6e, 0x52, 0x65, 0x67, + 0x65, 0x6e, 0x12, 0x20, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, 0x63, 0x72, + 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x75, 0x72, 0x6e, 0x52, + 0x65, 0x67, 0x65, 0x6e, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x75, 0x72, + 0x6e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xd5, + 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x65, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x72, + 0x65, 0x67, 0x65, 0x6e, 0x2d, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x72, 0x65, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2f, + 0x76, 0x31, 0x3b, 0x65, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x76, 0x31, 0xa2, 0x02, + 0x03, 0x52, 0x45, 0x58, 0xaa, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x2e, 0x45, 0x63, 0x6f, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x52, 0x65, 0x67, 0x65, + 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, + 0x1e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x5c, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x14, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x3a, 0x3a, 0x45, 0x63, 0x6f, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/regen/ecocredit/v1/tx_grpc.pb.go b/api/regen/ecocredit/v1/tx_grpc.pb.go index de6f12ef34..43a9de6f2e 100644 --- a/api/regen/ecocredit/v1/tx_grpc.pb.go +++ b/api/regen/ecocredit/v1/tx_grpc.pb.go @@ -73,7 +73,8 @@ type MsgClient interface { // CreateOrUpdateApplicaton creates a new project credit class application, updates // the metadata for an existing one when changes have been requested, or withdraws // the application. When an application is withdrawn, its data will be deleted from - // state and the project may apply again to the same credit class in the future. + // state and the project may apply again to the same credit class in the future. Any + // new metadata will be passed to EventUpdateApplication including for withdrawals. // // Since Revision 3 CreateOrUpdateApplication(ctx context.Context, in *MsgCreateOrUpdateApplication, opts ...grpc.CallOption) (*MsgCreateOrUpdateApplicationResponse, error) @@ -168,8 +169,8 @@ type MsgClient interface { // the scope of the provided credit class, the credits will be minted to the // existing credit batch, otherwise the credits will be issued in a new credit // batch. The new credit batch will be created under an existing project if a - // project with a matching reference id already exists within the scope of the - // credit class, otherwise a new project will be created. + // project with a matching reference id already exists, otherwise a new project + // will be created. BridgeReceive(ctx context.Context, in *MsgBridgeReceive, opts ...grpc.CallOption) (*MsgBridgeReceiveResponse, error) // AddCreditType is a governance method that allows the addition of new // credit types to the network. @@ -507,7 +508,8 @@ type MsgServer interface { // CreateOrUpdateApplicaton creates a new project credit class application, updates // the metadata for an existing one when changes have been requested, or withdraws // the application. When an application is withdrawn, its data will be deleted from - // state and the project may apply again to the same credit class in the future. + // state and the project may apply again to the same credit class in the future. Any + // new metadata will be passed to EventUpdateApplication including for withdrawals. // // Since Revision 3 CreateOrUpdateApplication(context.Context, *MsgCreateOrUpdateApplication) (*MsgCreateOrUpdateApplicationResponse, error) @@ -602,8 +604,8 @@ type MsgServer interface { // the scope of the provided credit class, the credits will be minted to the // existing credit batch, otherwise the credits will be issued in a new credit // batch. The new credit batch will be created under an existing project if a - // project with a matching reference id already exists within the scope of the - // credit class, otherwise a new project will be created. + // project with a matching reference id already exists, otherwise a new project + // will be created. BridgeReceive(context.Context, *MsgBridgeReceive) (*MsgBridgeReceiveResponse, error) // AddCreditType is a governance method that allows the addition of new // credit types to the network. diff --git a/proto/regen/ecocredit/v1/query.proto b/proto/regen/ecocredit/v1/query.proto index 1545a73457..2727546a01 100644 --- a/proto/regen/ecocredit/v1/query.proto +++ b/proto/regen/ecocredit/v1/query.proto @@ -270,8 +270,8 @@ service Query { }; } - // ProjectEnrollments queries all credit class enrollments associated with a - // project. + // ProjectEnrollments queries all credit class enrollments and allows for filtering by + // project or credit class. rpc ProjectEnrollments(QueryProjectEnrollmentsRequest) returns (QueryProjectEnrollmentsResponse) { option (google.api.http) = { get : "/regen/ecocredit/v1/project/{project_id}/enrollments" @@ -702,9 +702,8 @@ message ProjectInfo { // admin is the admin of the project. string admin = 2; - // class_id is the unique identifier of the credit class within which the - // project was created. - string class_id = 3; + // Deprecated: use ProjectEnrollment instead. + string class_id = 3 [deprecated = true]; // jurisdiction is the jurisdiction of the project. Full documentation can be // found in MsgCreateProject.jurisdiction. @@ -863,16 +862,21 @@ message QueryProjectEnrollmentRequest { message QueryProjectEnrollmentResponse { // project_class is the fetched project class relationship. - ProjectEnrollment project_class = 1; + EnrollmentInfo enrollment = 1; } // QueryProjectEnrollmentsRequest is the Query/ProjectEnrollments request type. // // Since Revision 3 message QueryProjectEnrollmentsRequest { - // project_id is the unique identifier of the project to query. + // project_id is the unique identifier of the project to filter enrollments + // by. If not set, enrollments for all projects will be returned. string project_id = 1; + // class_id is the unique identifier of the credit class to filter enrollments + // by. If not set, enrollments for all credit classes will be returned. + string class_id = 3; + // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 2; } @@ -883,8 +887,28 @@ message QueryProjectEnrollmentsRequest { message QueryProjectEnrollmentsResponse { // enrollments are the fetched project credit class enrollments. - repeated ProjectEnrollment enrollments = 1; + repeated EnrollmentInfo enrollments = 1; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// EnrollmentInfo is the human-readable project enrollment information. +message EnrollmentInfo { + // project_id is the unique identifier of the project to query. + string project_id = 1; + + // class_id is the unique identifier of the credit class to query. + string class_id = 2; + + // status is the status of the enrollment. + ProjectEnrollmentStatus status = 4; + + // application_metadata is any arbitrary metadata set by the project + // admin related to its application to the credit class. + string application_metadata = 5; + + // enrollment_metadata is any arbitrary metadata set by the credit class + // admin evaluating the project's application to the credit class. + string enrollment_metadata = 6; } \ No newline at end of file diff --git a/proto/regen/ecocredit/v1/state.proto b/proto/regen/ecocredit/v1/state.proto index 10e485ee99..5ce1dbd193 100644 --- a/proto/regen/ecocredit/v1/state.proto +++ b/proto/regen/ecocredit/v1/state.proto @@ -19,6 +19,8 @@ message CreditType { // abbreviation is a 1-3 character uppercase abbreviation of the CreditType // name, used in batch denominations within the CreditType. It must be unique. + // The letter P is reserved as the project prefix and cannot be used as a + // credit type to avoid confusion. string abbreviation = 1; // name is the name of the credit type (e.g. carbon, biodiversity). @@ -91,16 +93,14 @@ message Project { // efficient lookups. This identifier is auto-incrementing. uint64 key = 1; - // id is the unique identifier of the project either auto-generated from the - // credit class id and project sequence number or provided upon creation. + // id is the auto-generated unique identifier of the project. string id = 2; // admin is the admin of the project. bytes admin = 3; - // class_key is the table row identifier of the credit class used internally - // for efficient lookups. This links a project to a credit class. - uint64 class_key = 4; + // Deprecated: use ProjectEnrollment instead. + uint64 class_key = 4 [deprecated = true]; // jurisdiction is the jurisdiction of the project. // Full documentation can be found in MsgCreateProject.jurisdiction. @@ -183,9 +183,10 @@ message ClassSequence { uint64 next_sequence = 2; } -// ProjectSequence stores and increments the sequence number for projects within -// a credit class. +// Deprecated: No longer used. message ProjectSequence { + option deprecated = true; + option (cosmos.orm.v1.table) = { id : 7, primary_key : {fields : "class_key"} diff --git a/proto/regen/ecocredit/v1/tx.proto b/proto/regen/ecocredit/v1/tx.proto index 84ea41c7f1..3fbc298b50 100644 --- a/proto/regen/ecocredit/v1/tx.proto +++ b/proto/regen/ecocredit/v1/tx.proto @@ -38,7 +38,8 @@ service Msg { // CreateOrUpdateApplicaton creates a new project credit class application, updates // the metadata for an existing one when changes have been requested, or withdraws // the application. When an application is withdrawn, its data will be deleted from - // state and the project may apply again to the same credit class in the future. + // state and the project may apply again to the same credit class in the future. Any + // new metadata will be passed to EventUpdateApplication including for withdrawals. // // Since Revision 3 rpc CreateOrUpdateApplication(MsgCreateOrUpdateApplication) @@ -157,8 +158,8 @@ service Msg { // the scope of the provided credit class, the credits will be minted to the // existing credit batch, otherwise the credits will be issued in a new credit // batch. The new credit batch will be created under an existing project if a - // project with a matching reference id already exists within the scope of the - // credit class, otherwise a new project will be created. + // project with a matching reference id already exists, otherwise a new project + // will be created. rpc BridgeReceive(MsgBridgeReceive) returns (MsgBridgeReceiveResponse); // AddCreditType is a governance method that allows the addition of new @@ -348,16 +349,12 @@ message MsgCreateUnregisteredProject { // increased precision. string jurisdiction = 3; - // reference_id is any arbitrary string used to reference the project with a - // maximum length of 32 characters. - string reference_id = 4; - // fee is the project creation fee. An equal fee is required if the project // creation fee parameter is set. The provided fee can be greater than the // parameter, but only the amount in the parameter will be charged. // // Since Revision 3 - cosmos.base.v1beta1.Coin fee = 5; + cosmos.base.v1beta1.Coin fee = 4; } // MsgCreateUnregisteredProjectResponse is the Msg/CreateUnregisteredProject response type. diff --git a/x/ecocredit/base/client/query.go b/x/ecocredit/base/client/query.go index b49fcde510..cca9114e77 100644 --- a/x/ecocredit/base/client/query.go +++ b/x/ecocredit/base/client/query.go @@ -667,3 +667,66 @@ func QueryAllowedBridgeChainsCmd() *cobra.Command { flags.AddPaginationFlagsToCmd(cmd, "allowed-bridge-chains") return qflags(cmd) } + +func QueryProjectEnrollment() *cobra.Command { + cmd := &cobra.Command{ + Use: "project-enrollment [project-id] [class-id]", + Short: "Retrieve project enrollment information", + Long: "Retrieve project enrollment information.", + Example: "regen q ecocredit project-enrollment P001 C01", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + c, ctx, err := mkQueryClient(cmd) + if err != nil { + return err + } + res, err := c.ProjectEnrollment(cmd.Context(), &types.QueryProjectEnrollmentRequest{ + ProjectId: args[0], + ClassId: args[1], + }) + return printQueryResponse(ctx, res, err) + }, + } + return qflags(cmd) +} + +func QueryProjectEnrollments() *cobra.Command { + var projectID, classID string + + cmd := &cobra.Command{ + Use: "project-enrollments", + Short: "Retrieve project enrollments", + Long: `Retrieve project enrollments with optional pagination and filtering by project or credit class. + +Flags: + --project string Filter by project ID + --class string Filter by credit class ID +`, + Example: `regen q ecocredit project-enrollments --limit 10 --offset 10 +regen q ecocredit project-enrollments --project P001 +regen q ecocredit project-enrollments --class C01`, + RunE: func(cmd *cobra.Command, args []string) error { + c, ctx, err := mkQueryClient(cmd) + if err != nil { + return err + } + + pagination, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := c.ProjectEnrollments(cmd.Context(), &types.QueryProjectEnrollmentsRequest{ + ProjectId: projectID, + ClassId: classID, + Pagination: pagination, + }) + return printQueryResponse(ctx, res, err) + }, + } + + cmd.Flags().StringVar(&projectID, FlagProject, "", "Filter by project ID") + cmd.Flags().StringVar(&classID, FlagClass, "", "Filter by credit class ID") + + return qflags(cmd) +} diff --git a/x/ecocredit/base/client/tx.go b/x/ecocredit/base/client/tx.go index b5f8191810..03a6338acb 100644 --- a/x/ecocredit/base/client/tx.go +++ b/x/ecocredit/base/client/tx.go @@ -22,10 +22,14 @@ const ( FlagAddIssuers string = "add-issuers" FlagReason string = "reason" FlagRemoveIssuers string = "remove-issuers" + FlagClass string = "class" + FlagProject string = "project" FlagReferenceID string = "reference-id" FlagRetirementJurisdiction string = "retirement-jurisdiction" FlagRetirementReason string = "retirement-reason" FlagClassFee string = "class-fee" + FlagProjectFee string = "project-fee" + FlagMetadata string = "metadata" ) // TxCreateClassCmd returns a transaction command that creates a credit class. @@ -109,48 +113,77 @@ regen tx ecocredit create-class regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw,reg // TxCreateProjectCmd returns a transaction command that creates a new project. func TxCreateProjectCmd() *cobra.Command { + var classID, referenceID, projectFee string + cmd := &cobra.Command{ - Use: "create-project [class-id] [jurisdiction] [metadata] [flags]", - Short: "Create a new project within a credit class", - Long: `Create a new project within a credit class. + Use: "create-project [jurisdiction] [metadata] [flags]", + Short: "Create a new project", + Long: `Create a new project. By default, this creates an unregistered project that is not enrolled in any credit +class. If the class-id flag is provided, the signer must be an issuer of the class and the project will be enrolled in +the class automatically. Parameters: -- class-id: the ID of the credit class - jurisdiction: the jurisdiction of the project - metadata: any arbitrary metadata to attach to the project -Optional Flags: +Flags: -- reference-id: a reference ID for the project`, - Example: `regen tx ecocredit create-project C01 "US-WA 98225" regen:13toVgf5UjYBz6J29x28pLQyjKz5FpcW3f4bT5uRKGxGREWGKjEdXYG.rdf -regen tx ecocredit create-project C01 "US-WA 98225" regen:13toVgf5UjYBz6J29x28pLQyjKz5FpcW3f4bT5uRKGxGREWGKjEdXYG.rdf --reference-id VCS-001`, - Args: cobra.ExactArgs(3), +- project-fee: the fee that the project creator will pay to create the project. It must be >= the +required project creation fee param. If the project creation fee is zero, no fee is required. +We explicitly include the project creation fee here so that the project creator acknowledges paying +the fee and is not surprised to learn that the they paid a fee without consent. +- class: the ID of the credit class. If this is provided, the signer must be an issuer of the class. +- reference-id: a reference ID for the project. Only valid if class-id is also provided.`, + Example: `regen tx ecocredit create-project "US-WA 98225" regen:13toVgf5UjYBz6J29x28pLQyjKz5FpcW3f4bT5uRKGxGREWGKjEdXYG.rdf +regen tx ecocredit create-project "US-WA 98225" regen:13toVgf5UjYBz6J29x28pLQyjKz5FpcW3f4bT5uRKGxGREWGKjEdXYG.rdf --class-id C01 --reference-id VCS-001`, + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := sdkclient.GetClientTxContext(cmd) if err != nil { return err } - referenceID, err := cmd.Flags().GetString(FlagReferenceID) - if err != nil { - return err + jurisdiction := args[0] + metadata := args[1] + + // parse and normalize project fee + var fee sdk.Coin + if projectFee != "" { + var err error + fee, err = sdk.ParseCoinNormalized(projectFee) + if err != nil { + return fmt.Errorf("failed to parse class-fee: %w", err) + } } - msg := types.MsgCreateProject{ - Admin: clientCtx.GetFromAddress().String(), - ClassId: args[0], - Jurisdiction: args[1], - Metadata: args[2], - ReferenceId: referenceID, + var msg sdk.Msg + if classID != "" { + msg = &types.MsgCreateProject{ + Admin: clientCtx.GetFromAddress().String(), + ClassId: classID, + Jurisdiction: jurisdiction, + Metadata: metadata, + ReferenceId: referenceID, + Fee: &fee, + } + } else { + msg = &types.MsgCreateUnregisteredProject{ + Admin: clientCtx.GetFromAddress().String(), + Jurisdiction: jurisdiction, + Metadata: metadata, + Fee: &fee, + } } - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, } - cmd.Flags().String(FlagReferenceID, "", "a reference ID for the project") + cmd.Flags().StringVar(&classID, FlagClass, "", "the ID of the credit class into which the project will be enrolled") + cmd.Flags().StringVar(&referenceID, FlagReferenceID, "", "a reference ID for the project") + cmd.Flags().StringVar(&projectFee, FlagProjectFee, "", "the fee that the project creator will pay to create the project (e.g. \"20regen\")") return txFlags(cmd) } @@ -159,7 +192,7 @@ regen tx ecocredit create-project C01 "US-WA 98225" regen:13toVgf5UjYBz6J29x28pL // represent a new credit batch. func TxGenBatchJSONCmd() *cobra.Command { cmd := &cobra.Command{ - Use: `gen-batch-json [issuer] [project-id] [issuance-count] [metadata] [start-date] [end-date]`, + Use: `gen-batch-json [issuer] [project-id] [class-id] [issuance-count] [metadata] [start-date] [end-date]`, Short: "Generates JSON to represent a new credit batch for use with create-batch command", Long: `Generates JSON to represent a new credit batch for use with create-batch command. @@ -167,6 +200,7 @@ Parameters: - issuer: the account address of the credit batch issuer - project-id: the ID of the project +- class-id: the ID of the credit class to which the batch belongs and in which the project is enrolled - issuance-count: the number of issuance items to generate - metadata: any arbitrary metadata to attach to the credit batch - start-date: the beginning of the period during which this credit batch was @@ -174,9 +208,9 @@ Parameters: - end-date: the end of the period during which this credit batch was quantified and verified (format: yyyy-mm-dd)`, Example: "regen tx ecocredit gen-batch-json regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw C01-001 2 regen:13toVgf5UjYBz6J29x28pLQyjKz5FpcW3f4bT5uRKGxGREWGKjEdXYG.rdf 2020-01-01 2021-01-01", - Args: cobra.ExactArgs(6), + Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { - issuanceCount, err := strconv.ParseUint(args[2], 10, 8) + issuanceCount, err := strconv.ParseUint(args[3], 10, 8) if err != nil { return err } @@ -186,12 +220,12 @@ Parameters: issuance[i] = &types.BatchIssuance{} } - startDate, err := regentypes.ParseDate("start date", args[4]) + startDate, err := regentypes.ParseDate("start date", args[5]) if err != nil { return err } - endDate, err := regentypes.ParseDate("end date", args[5]) + endDate, err := regentypes.ParseDate("end date", args[6]) if err != nil { return err } @@ -199,8 +233,9 @@ Parameters: msg := &types.MsgCreateBatch{ Issuer: args[0], ProjectId: args[1], + ClassId: args[2], Issuance: issuance, - Metadata: args[3], + Metadata: args[4], StartDate: &startDate, EndDate: &endDate, } @@ -795,3 +830,134 @@ Example JSON: return txFlags(cmd) } + +func TxCreateOrUpdateApplicationCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-or-update-application [project-id] [class-id] [flags]", + Short: "Create or update an application", + Long: `Create or update an application. + +Parameters: +- project-id: the ID of the project creating or updating the application +- class-id: the ID of the credit class to which the application is being made + + +Flags: + +- metadata: optional metadata to attach to the application +`, + Example: `regen tx ecocredit create-or-update-application P001 C01 --metadata regen:13toVgf5UjYBz6J29x28pLQyjKz5FpcW3f4bT5uRKGxGREWGKjEdXYG.rdf`, + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + return runCreateOrUpdateApplication(cmd, args, false) + }, + } + + cmd.Flags().String(FlagMetadata, "", "optional metadata to attach to the application") + + return txFlags(cmd) +} + +func TxWithdrawApplicationCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "withdraw-application [project-id] [class-id] [flags]", + Short: "Withdraw an application", + Long: `Withdraw an application. + +Parameters: +- project-id: the ID of the project withdrawing the application +- class-id: the ID of the credit class from which the application is being withdrawn + +Flags: + +- metadata: optional metadata to attach to the withdrawal +`, + Example: `regen tx ecocredit withdraw-application P001 C01`, + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + return runCreateOrUpdateApplication(cmd, args, true) + }, + } + + cmd.Flags().String(FlagMetadata, "", "optional metadata to attach to the withdrawal") + + return txFlags(cmd) +} + +func runCreateOrUpdateApplication(cmd *cobra.Command, args []string, withdraw bool) error { + clientCtx, err := sdkclient.GetClientTxContext(cmd) + if err != nil { + return err + } + + metadata, err := cmd.Flags().GetString(FlagMetadata) + if err != nil { + return err + } + + msg := &types.MsgCreateOrUpdateApplication{ + ProjectAdmin: clientCtx.GetFromAddress().String(), + ProjectId: args[0], + ClassId: args[1], + Metadata: metadata, + Withdraw: withdraw, + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) +} + +func TxUpdateProjectEnrollment() *cobra.Command { + var metadata string + + cmd := &cobra.Command{ + Use: "update-project-enrollment [project-id] [class-id] [status] [flags]", + Short: "Update project enrollment", + Long: `Update project enrollment. + +Parameters: +- project-id: the ID of the project to update +- class-id: the ID of the credit class to update +- status: the new status of the project enrollment, must be one of ACCEPTED, CHANGES_REQUESTED, REJECTED or TERMINATED + +Flags: +- metadata: optional metadata to attach to the enrollment +`, + Example: `regen tx ecocredit update-project-enrollment P001 C01 ACCEPTED --metadata regen:13toVgf5UjYBz6J29x28pLQyjKz5FpcW3f4bT5uRKGxGREWGKjEdXYG.rdf`, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := sdkclient.GetClientTxContext(cmd) + if err != nil { + return err + } + + statusArg := args[2] + var status types.ProjectEnrollmentStatus + switch statusArg { + case "ACCEPTED": + status = types.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED + case "CHANGES_REQUESTED": + status = types.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_CHANGES_REQUESTED + case "REJECTED": + status = types.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_REJECTED + case "TERMINATED": + status = types.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_TERMINATED + default: + return fmt.Errorf("invalid status: %s", statusArg) + } + + msg := &types.MsgUpdateProjectEnrollment{ + Issuer: clientCtx.GetFromAddress().String(), + ProjectId: args[0], + ClassId: args[1], + NewStatus: status, + Metadata: metadata, + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().StringVar(&metadata, FlagMetadata, "", "optional metadata to attach to the enrollment") + + return txFlags(cmd) +} diff --git a/x/ecocredit/base/keeper/features/msg_bridge_receive.feature b/x/ecocredit/base/keeper/features/msg_bridge_receive.feature index f806293fd8..46c04d103c 100644 --- a/x/ecocredit/base/keeper/features/msg_bridge_receive.feature +++ b/x/ecocredit/base/keeper/features/msg_bridge_receive.feature @@ -49,8 +49,8 @@ Feature: Msg/BridgeReceive Given a credit type with abbreviation "C" And a credit class with id "C01" and issuer alice And allowed bridge chain "polygon" - And a project with id "C01-001" - And a credit batch with denom "C01-001-20200101-20210101-001" and issuer alice + And a project with id "P001" + And a credit batch with denom "C01-P001-20200101-20210101-001" and issuer alice And the batch contract """ { @@ -133,7 +133,7 @@ Feature: Msg/BridgeReceive Then expect project properties """ { - "id": "C01-001", + "id": "P001", "reference_id": "VCS-001", "metadata": "regen:13toVfvC2YxrrfSXWB5h2BGHiXZURsKxWUz72uDRDSPMCrYPguGUXSC.rdf", "jurisdiction": "US-WA" @@ -161,7 +161,7 @@ Feature: Msg/BridgeReceive Then expect batch properties """ { - "denom": "C01-001-20200101-20210101-001", + "denom": "C01-P001-20200101-20210101-001", "metadata": "regen:13toVfvC2YxrrfSXWB5h2BGHiXZURsKxWUz72uDRDSPMCrYPguGUXSC.rdf", "start_date": "2020-01-01T00:00:00Z", "end_date": "2021-01-01T00:00:00Z" @@ -231,8 +231,8 @@ Feature: Msg/BridgeReceive Given a credit type with abbreviation "C" And a credit class with id "C01" and issuer alice And allowed bridge chain "polygon" - And a project with id "C01-001" - And a credit batch with denom "C01-001-20200101-20210101-001" and issuer alice + And a project with id "P001" + And a credit batch with denom "C01-P001-20200101-20210101-001" and issuer alice And the batch contract """ { @@ -245,8 +245,8 @@ Feature: Msg/BridgeReceive Then expect event with properties """ { - "project_id": "C01-001", - "batch_denom": "C01-001-20200101-20210101-001", + "project_id": "P001", + "batch_denom": "C01-P001-20200101-20210101-001", "amount": "10", "origin_tx": { "id": "0x7a70692a348e8688f54ab2bdfe87d925d8cc88932520492a11eaa02dc128243e", diff --git a/x/ecocredit/base/keeper/features/msg_create_batch.feature b/x/ecocredit/base/keeper/features/msg_create_batch.feature index 732a3e1c1e..c4084a26bf 100644 --- a/x/ecocredit/base/keeper/features/msg_create_batch.feature +++ b/x/ecocredit/base/keeper/features/msg_create_batch.feature @@ -18,29 +18,29 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: the project exists - When alice attempts to create a batch with project id "C01-001" + When alice attempts to create a batch with project id "P001" and class id "C01" Then expect no error Scenario: the project does not exist - When alice attempts to create a batch with project id "C01-002" - Then expect the error "could not get project with id C01-002: not found: invalid request" + When alice attempts to create a batch with project id "P002" and class id "C02" + Then expect error contains "could not get project with id P002: not found: invalid request" Rule: The issuer must be an allowed credit class issuer Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: the issuer is an allowed credit class issuer - When alice attempts to create a batch with project id "C01-001" + When alice attempts to create a batch with project id "P001" and class id "C01" Then expect no error Scenario: the issuer is not an allowed credit class issuer - When bob attempts to create a batch with project id "C01-001" + When bob attempts to create a batch with project id "P001" and class id "C01" Then expect error contains "is not an issuer for the class: unauthorized" Rule: The decimal places in issuance amount must not exceed credit type precision @@ -48,10 +48,10 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" and precision "6" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario Outline: the decimal places in tradable amount is less than or equal to credit type precision - When alice attempts to create a batch with project id "C01-001" and tradable amount "" + When alice attempts to create a batch for project "P001" and class "C01" with tradable amount "" Then expect no error Examples: @@ -60,11 +60,11 @@ Feature: Msg/CreateBatch | equal to | 9.123456 | Scenario: the decimal places in tradable amount is greater than credit type precision - When alice attempts to create a batch with project id "C01-001" and tradable amount "9.1234567" + When alice attempts to create a batch for project "P001" and class "C01" with tradable amount "9.1234567" Then expect the error "9.1234567 exceeds maximum decimal places: 6: invalid request" Scenario Outline: the decimal places in retired amount is less than or equal to credit type precision - When alice attempts to create a batch with project id "C01-001" and retired amount "" + When alice attempts to create a batch for project "P001" and class "C01" with retired amount "" Then expect no error Examples: @@ -73,7 +73,7 @@ Feature: Msg/CreateBatch | equal to | 9.123456 | Scenario: the decimal places in retired amount is greater than credit type precision - When alice attempts to create a batch with project id "C01-001" and retired amount "9.1234567" + When alice attempts to create a batch for project "P001" and class "C01" with retired amount "9.1234567" Then expect the error "9.1234567 exceeds maximum decimal places: 6: invalid request" Rule: The origin tx must be unique within the scope of the credit class @@ -81,7 +81,7 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: the origin tx is not unique within the credit class Given an origin tx index @@ -92,7 +92,7 @@ Feature: Msg/CreateBatch "source": "polygon" } """ - When alice attempts to create a batch with project id "C01-001" and origin tx + When alice attempts to create a batch with project "P001" class "C01" and origin tx """ { "id": "0x64", @@ -110,7 +110,7 @@ Feature: Msg/CreateBatch "source": "polygon" } """ - When alice attempts to create a batch with project id "C01-001" and origin tx + When alice attempts to create a batch with project "P001" class "C01" and origin tx """ { "id": "0x64", @@ -124,7 +124,7 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: the contract is not unique within credit class Given a batch contract @@ -135,7 +135,7 @@ Feature: Msg/CreateBatch "contract": "0x40" } """ - When alice attempts to create a batch with project id "C01-001" and origin tx + When alice attempts to create a batch with project "P001" class "C01" and origin tx """ { "id": "0x64", @@ -154,7 +154,7 @@ Feature: Msg/CreateBatch "contract": "0x40" } """ - When alice attempts to create a batch with project id "C01-001" and origin tx + When alice attempts to create a batch with project "P001" class "C01" and origin tx """ { "id": "0x64", @@ -169,10 +169,10 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: balance updated from issuance with single item - When alice attempts to create a batch with project id "C01-001" and issuance + When alice attempts to create a batch with project "P001" class "C01" and issuance """ [ { @@ -193,7 +193,7 @@ Feature: Msg/CreateBatch """ Scenario: balance updated from issuance with multiple items and same recipient - When alice attempts to create a batch with project id "C01-001" and issuance + When alice attempts to create a batch with project "P001" class "C01" and issuance """ [ { @@ -220,7 +220,7 @@ Feature: Msg/CreateBatch """ Scenario: balance updated from issuance with multiple items and different recipients - When alice attempts to create a batch with project id "C01-001" and issuance + When alice attempts to create a batch with project "P001" class "C01" and issuance """ [ { @@ -261,10 +261,10 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: supply updated from issuance with single item - When alice attempts to create a batch with project id "C01-001" and issuance + When alice attempts to create a batch with project "P001" class "C01" and issuance """ [ { @@ -285,7 +285,7 @@ Feature: Msg/CreateBatch """ Scenario: supply updated from issuance with multiple items - When alice attempts to create a batch with project id "C01-001" and issuance + When alice attempts to create a batch with project "P001" class "C01" and issuance """ [ { @@ -318,18 +318,18 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" - And a project with project id "C01-002" + And a project with project id "P001" enrolled in "C01" + And a project with project id "P002" enrolled in "C01" Scenario: the batch sequence is updated - Given a batch sequence with project id "C01-001" and next sequence "1" - When alice attempts to create a batch with project id "C01-001" - Then expect batch sequence with project id "C01-001" and next sequence "2" + Given a batch sequence with project id "P001" and next sequence "1" + When alice attempts to create a batch with project id "P001" and class id "C01" + Then expect batch sequence with project id "P001" and next sequence "2" Scenario: the batch sequence is not updated - Given a batch sequence with project id "C01-001" and next sequence "1" - When alice attempts to create a batch with project id "C01-002" - Then expect batch sequence with project id "C01-001" and next sequence "1" + Given a batch sequence with project id "P001" and next sequence "1" + When alice attempts to create a batch with project id "P002" and class id "C01" + Then expect batch sequence with project id "P001" and next sequence "1" # no failing scenario - state transitions only occur upon successful message execution @@ -338,13 +338,14 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: the batch properties are added When alice attempts to create a batch with properties """ { - "project_id": "C01-001", + "project_id": "P001", + "class_id": "C01", "metadata": "regen:13toVfvC2YxrrfSXWB5h2BGHiXZURsKxWUz72uDRDSPMCrYPguGUXSC.rdf", "start_date": "2020-01-01T00:00:00Z", "end_date": "2021-01-01T00:00:00Z", @@ -354,11 +355,12 @@ Feature: Msg/CreateBatch Then expect batch properties """ { - "denom": "C01-001-20200101-20210101-001", + "denom": "C01-P001-20200101-20210101-001", "metadata": "regen:13toVfvC2YxrrfSXWB5h2BGHiXZURsKxWUz72uDRDSPMCrYPguGUXSC.rdf", "start_date": "2020-01-01T00:00:00Z", "end_date": "2021-01-01T00:00:00Z", - "open": true + "open": true, + "class_key": 1 } """ @@ -369,10 +371,10 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: the batch contract mapping is added - When alice attempts to create a batch with project id "C01-001" and origin tx + When alice attempts to create a batch with project "P001" class "C01" and origin tx """ { "id": "0x64", @@ -396,14 +398,14 @@ Feature: Msg/CreateBatch Background: Given a credit type with abbreviation "C" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: the response includes the batch denom - When alice attempts to create a batch with project id "C01-001" + When alice attempts to create a batch with project id "P001" and class id "C01" Then expect the response """ { - "batch_denom": "C01-001-20200101-20210101-001" + "batch_denom": "C01-P001-20200101-20210101-001" } """ @@ -415,15 +417,15 @@ Feature: Msg/CreateBatch Given a credit type with abbreviation "C" And ecocredit module's address "regen15406g34dl5v9780tx2q3vtjdpkdgq4hhegdtm9" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: Event EventRetire is emitted - When creates a batch from project "C01-001" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" with reason "offsetting electricity consumption" + When creates a batch from project "P001" class "C01" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" with reason "offsetting electricity consumption" Then expect event retire with properties """ { "owner": "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8", - "batch_denom": "C01-001-20200101-20210101-001", + "batch_denom": "C01-P001-20200101-20210101-001", "amount": "10", "jurisdiction": "US-WA", "reason": "offsetting electricity consumption" @@ -431,68 +433,68 @@ Feature: Msg/CreateBatch """ Scenario: Event EventMint is emitted - When creates a batch from project "C01-001" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" + When creates a batch from project "P001" class "C01" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" Then expect event mint with properties """ { - "batch_denom": "C01-001-20200101-20210101-001", + "batch_denom": "C01-P001-20200101-20210101-001", "tradable_amount": "0", "retired_amount": "10" } """ Scenario: Event EventTransfer is emitted - When creates a batch from project "C01-001" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" + When creates a batch from project "P001" class "C01" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" Then expect event transfer with properties """ { "sender": "regen15406g34dl5v9780tx2q3vtjdpkdgq4hhegdtm9", "recipient": "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8", - "batch_denom": "C01-001-20200101-20210101-001", + "batch_denom": "C01-P001-20200101-20210101-001", "tradable_amount": "0", "retired_amount": "10" } """ Scenario: Event EventCreateBatch is emitted - When creates a batch from project "C01-001" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" + When creates a batch from project "P001" class "C01" and issues "10" retired credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" from "US-WA" Then expect event create batch with properties """ { - "batch_denom": "C01-001-20200101-20210101-001" + "batch_denom": "C01-P001-20200101-20210101-001" } """ Scenario: Event EventMint is emitted - When creates a batch from project "C01-001" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" + When creates a batch from project "P001" class "C01" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" Then expect event mint with properties """ { - "batch_denom": "C01-001-20200101-20210101-001", + "batch_denom": "C01-P001-20200101-20210101-001", "tradable_amount": "10", "retired_amount": "0" } """ Scenario: Event EventTransfer is emitted - When creates a batch from project "C01-001" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" + When creates a batch from project "P001" class "C01" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" And expect event transfer with properties """ { "sender": "regen15406g34dl5v9780tx2q3vtjdpkdgq4hhegdtm9", "recipient": "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8", - "batch_denom": "C01-001-20200101-20210101-001", + "batch_denom": "C01-P001-20200101-20210101-001", "tradable_amount": "10", "retired_amount": "0" } """ Scenario: Event EventCreateBatch is emitted - When creates a batch from project "C01-001" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" + When creates a batch from project "P001" class "C01" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" Then expect event create batch with properties """ { - "batch_denom": "C01-001-20200101-20210101-001" + "batch_denom": "C01-P001-20200101-20210101-001" } """ @@ -511,14 +513,14 @@ Feature: Msg/CreateBatch """ And ecocredit module's address "regen15406g34dl5v9780tx2q3vtjdpkdgq4hhegdtm9" And a credit class with class id "C01" and issuer alice - And a project with project id "C01-001" + And a project with project id "P001" enrolled in "C01" Scenario: Event EventCreateBatch is emitted - When creates a batch from project "C01-001" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" + When creates a batch from project "P001" class "C01" and issues "10" tradable credits to "regen1sl2dsfyf2znn48ehwqg28cv3nuglxkx4h7q5l8" Then expect event create batch with properties """ { - "batch_denom": "C01-001-20200101-20210101-001", + "batch_denom": "C01-P001-20200101-20210101-001", "origin_tx": { "id": "0x123", "source": "polygon", diff --git a/x/ecocredit/base/keeper/features/msg_create_or_update_application.feature b/x/ecocredit/base/keeper/features/msg_create_or_update_application.feature new file mode 100644 index 0000000000..bc2877059d --- /dev/null +++ b/x/ecocredit/base/keeper/features/msg_create_or_update_application.feature @@ -0,0 +1,64 @@ +Feature: Msg/CreateOrUpdateApplication + + Background: + Given project "P001" with admin "Alice" + And credit class "C01" + + Rule: when there is no application for the project, the project admin can create an application + Background: + Given an application for "P001" to "C01" does not exist + + Scenario: admin creates an application + When "Alice" creates or updates an application for "P001" to "C01" with metadata "xyz123" + Then expect no error + * expect the application for "P001" to "C01" exists with metadata "xyz123" + * expect EventUpdateApplication with properties + """ + { "project_id": "P001", "class_id": "C01", "action": "ACTION_CREATE", + "new_application_metadata": "xyz123" } + """ + + Scenario: non-admin attempts to create an application + When "Bob" creates or updates an application for "P001" to "C01" with metadata "xyz123" + Then expect error contains "unauthorized" + And an application for "P001" to "C01" does not exist + + Rule: when there is an existing application, the project admin can update the metadata + Background: + Given an application for "P001" to "C01" with metadata "abc123" + + Scenario: admin updates the application metadata + When "Alice" creates or updates an application for "P001" to "C01" with metadata "foobar379" + Then expect no error + * expect the application for "P001" to "C01" exists with metadata "foobar379" + * expect EventUpdateApplication with properties + """ + { "project_id": "P001", "class_id": "C01", "action": "ACTION_UPDATE", + "new_application_metadata": "foobar379" } + """ + + Scenario: non-admin attempts to update the application metadata + When "Bob" creates or updates an application for "P001" to "C01" with metadata "foobar379" + Then expect error contains "unauthorized" + And expect the application for "P001" to "C01" exists with metadata "abc123" + + Rule: when there is an existing application, the project admin can withdraw the application and it is removed from state + Background: + Given an application for "P001" to "C01" with metadata "abc123" + + Scenario: admin withdraws the application + When "Alice" attempts to withdraw the application for "P001" to "C01" with metadata "foobar379" + Then expect no error + * an application for "P001" to "C01" does not exist + * expect EventUpdateApplication with properties + """ + { "project_id": "P001", "class_id": "C01", "action": "ACTION_WITHDRAW", + "new_application_metadata": "foobar379" } + """ + + Scenario: non-admin attempts to withdraw the application + When "Bob" attempts to withdraw the application for "P001" to "C01" with metadata "bob123" + Then expect error contains "unauthorized" + And expect the application for "P001" to "C01" exists with metadata "abc123" + + Rule: events get emitted diff --git a/x/ecocredit/base/keeper/features/msg_create_project.feature b/x/ecocredit/base/keeper/features/msg_create_project.feature index faa4ffe721..28a9c78fc4 100644 --- a/x/ecocredit/base/keeper/features/msg_create_project.feature +++ b/x/ecocredit/base/keeper/features/msg_create_project.feature @@ -4,7 +4,6 @@ Feature: CreateProject - when the credit class exists - when the admin is an allowed credit class issuer - when the non-empty reference id is unique within the scope of the credit class - - the project sequence is updated - the project properties are added - the response includes the project id @@ -43,39 +42,20 @@ Feature: CreateProject And a credit class with class id "C01" and issuer alice Scenario: non-empty reference id is unique within credit class - Given a project with project id "C01-001" and reference id "VCS-001" + Given a project "P001" in class "C01" with reference id "VCS-001" When alice attempts to create a project with class id "C01" and reference id "VCS-002" Then expect no error Scenario: empty reference id is allowed for multiple projects - Given a project with project id "C01-001" and reference id "" + Given a project "P001" in class "C01" with reference id "" When alice attempts to create a project with class id "C01" and reference id "" Then expect no error Scenario: non-empty reference id is not unique within credit class - Given a project with project id "C01-001" and reference id "VCS-001" + Given a project "P001" in class "C01" with reference id "VCS-001" When alice attempts to create a project with class id "C01" and reference id "VCS-001" Then expect the error "a project with reference id VCS-001 already exists within this credit class: invalid request" - Rule: the project sequence is updated - - Background: - Given a credit type with abbreviation "C" - And a credit class with class id "C01" and issuer alice - And a credit class with class id "C02" and issuer alice - - Scenario: the project sequence is updated - Given a project sequence with class id "C01" and next sequence "1" - When alice attempts to create a project with class id "C01" - Then expect project sequence with class id "C01" and next sequence "2" - - Scenario: the project sequence is not updated - Given a project sequence with class id "C01" and next sequence "1" - When alice attempts to create a project with class id "C02" - Then expect project sequence with class id "C01" and next sequence "1" - - # no failing scenario - state transitions only occur upon successful message execution - Rule: the project properties are added Background: @@ -95,7 +75,7 @@ Feature: CreateProject Then expect project properties """ { - "id": "C01-001", + "id": "P001", "metadata": "regen:13toVfvC2YxrrfSXWB5h2BGHiXZURsKxWUz72uDRDSPMCrYPguGUXSC.rdf", "jurisdiction": "US-WA", "reference_id": "VCS-001" @@ -115,7 +95,7 @@ Feature: CreateProject Then expect the response """ { - "project_id": "C01-001" + "project_id": "P001" } """ @@ -132,6 +112,6 @@ Feature: CreateProject Then expect event with properties """ { - "project_id": "C01-001" + "project_id": "P001" } """ diff --git a/x/ecocredit/base/keeper/features/msg_create_unregistered_project.feature b/x/ecocredit/base/keeper/features/msg_create_unregistered_project.feature new file mode 100644 index 0000000000..6113da5110 --- /dev/null +++ b/x/ecocredit/base/keeper/features/msg_create_unregistered_project.feature @@ -0,0 +1,37 @@ +Feature: CreateUnregisteredProject + Background: + Given project creation fee "100regen" + Given I have balance "150regen" + + Rule: a project can be created if the user pays the fee and has enough balance + Scenario: fee amount is sufficient + When I create a project with jurisdiction "US" and fee "100regen" + Then expect the project is created successfully + And expect balance "50regen" + + Scenario: fee amount is insufficient + When I create a project with jurisdiction "US" and fee "50regen" + Then expect error contains "insufficient fee" + And expect balance "150regen" + + Scenario: fee amount is more than required + When I create a project with jurisdiction "US" and fee "150regen" + Then expect the project is created successfully + And expect balance "50regen" + + Rule: a project cannot be created if has insufficient balance + Given I have balance "50regen" + When I create a project with jurisdiction "US" and fee "100regen" + Then expect error contains "insufficient balance" + And expect balance "50regen" + + Rule: creator is admin + When I create a project with jurisdiction "US" and fee "100regen" + Then expect the project is created successfully + And expect I am the admin + + Rule: jurisdiction and metadata are saved + When I create a project with jurisdiction "US", metadata "foobar" and fee "100regen" + Then expect the project is created successfully + And expect jurisdiction "US" + And expect metadata "foobar" diff --git a/x/ecocredit/base/keeper/features/msg_update_project_enrollment.feature b/x/ecocredit/base/keeper/features/msg_update_project_enrollment.feature new file mode 100644 index 0000000000..0c0d63405d --- /dev/null +++ b/x/ecocredit/base/keeper/features/msg_update_project_enrollment.feature @@ -0,0 +1,95 @@ +Feature: Msg/UpdateProjectEnrollment + + Background: + Given project "P001" + * class "C01" + * class issuer "I01" for "C01" + * class issuer "I02" for "C01" + + Rule: valid state transitions performed by issuers which don't remove enrollment entries are: + UNSPECIFIED -> CHANGES_REQUESTED or ACCEPTED + CHANGES_REQUESTED -> ACCEPTED + ACCEPTED -> ACCEPTED with new metadata + Scenario Outline: + Given enrollment for "P001" to "C01" is "" with metadata "" + When "" updates enrollment for "P001" to "C01" with status "" and metadata "" + Then expect error contains "" + And expect enrollment for "P001" to "C01" to be "" with metadata "" + And if no error expect EventUpdateProjectEnrollment with properties + """ + { + "issuer": "", "project_id": "P001", "class_id": "C01", + "old_status": "PROJECT_ENROLLMENT_STATUS_", + "new_status": "PROJECT_ENROLLMENT_STATUS_", + "new_enrollment_metadata": "" + } + """ + Examples: + | scenario | cur_status | cur_metadata | issuer | new_status | new_metadata | err | expected_status | expected_metadata | + | I01 unspecified to accepted | UNSPECIFIED | abc | I01 | ACCEPTED | foo123 | | ACCEPTED | foo123 | + | Bob unspecified to accepted | UNSPECIFIED | abc | Bob | ACCEPTED | foo123 | unauthorized | UNSPECIFIED | abc | + | I01 changes requested to accepted | CHANGES_REQUESTED | bar456 | I01 | ACCEPTED | foo123 | | ACCEPTED | foo123 | + | Bob changes requested to accepted | CHANGES_REQUESTED | bar456 | Bob | ACCEPTED | foo123 | unauthorized | CHANGES_REQUESTED | bar456 | + | I01 update accepted metadata | ACCEPTED | foo123 | I01 | ACCEPTED | bar357 | | ACCEPTED | bar357 | + | Bob updated accepted metadata | ACCEPTED | foo123 | Bob | ACCEPTED | bar357 | unauthorized | ACCEPTED | foo123 | + + Rule: valid state transitions performed by issuers which remove enrollment entries are: + UNSPECIFIED -> REJECTED + CHANGES_REQUESTED -> REJECTED + ACCEPTED -> TERMINATED + Scenario Outline: + Given enrollment for "P001" to "C01" is "" with metadata "" + When "" updates enrollment for "P001" to "C01" with status "" and metadata "" + Then expect error contains "" + And expect enrollment exists for "P001" to "C01" to be "" + And if no error expect EventUpdateProjectEnrollment with properties + """ + { + "issuer": "", "project_id": "P001", "class_id": "C01", + "old_status": "PROJECT_ENROLLMENT_STATUS_", + "new_status": "PROJECT_ENROLLMENT_STATUS_", + "new_enrollment_metadata": "" + } + """ + Examples: + | scenario | cur_status | cur_metadata | issuer | new_status | new_metadata | err | exists | + | IO1 unspecified to rejected | UNSPECIFIED | abc | I01 | REJECTED | baz789 | | false | + | Bob unspecified to rejected | UNSPECIFIED | abc | Bob | REJECTED | baz789 | unauthorized | true | + | I01 changes requested to rejected | CHANGES_REQUESTED | bar456 | I01 | REJECTED | baz789 | | false | + | Bob changes requested to rejected | CHANGES_REQUESTED | bar456 | Bob | REJECTED | baz789 | unauthorized | true | + | I01 accepted to rejected | ACCEPTED | foo123 | I01 | REJECTED | baz789 | invalid | true | + | Bob accepted to rejected | ACCEPTED | foo123 | Bob | REJECTED | baz789 | unauthorized | true | + | I01 unspecified to terminated | UNSPECIFIED | abc | I01 | TERMINATED | baz789 | invalid | true | + | Bob unspecified to terminated | UNSPECIFIED | abc | Bob | TERMINATED | baz789 | unauthorized | true | + | I01 changes requested to terminated | CHANGES_REQUESTED | bar456 | I01 | TERMINATED | baz789 | invalid | true | + | Bob changes requested to terminated | CHANGES_REQUESTED | bar456 | Bob | TERMINATED | baz789 | unauthorized | true | + | I01 accepted to terminated | ACCEPTED | foo123 | I01 | TERMINATED | baz789 | | false | + | Bob accepted to terminated | ACCEPTED | foo123 | Bob | TERMINATED | baz789 | unauthorized | true | + + Rule: any issuer can transition states + Scenario: Issuer 1 requests changes, issuer 2 accepts + Given enrollment for "P001" to "C01" is "UNSPECIFIED" with metadata "abc" + When "I01" updates enrollment for "P001" to "C01" with status "CHANGES_REQUESTED" and metadata "def" + Then expect no error + And expect enrollment for "P001" to "C01" to be "CHANGES_REQUESTED" with metadata "def" + And expect EventUpdateProjectEnrollment with properties + """ + { + "issuer": "I01", "project_id": "P001", "class_id": "C01", + "old_status": "PROJECT_ENROLLMENT_STATUS_UNSPECIFIED", + "new_status": "PROJECT_ENROLLMENT_STATUS_CHANGES_REQUESTED", + "new_enrollment_metadata": "def" + } + """ + When "I02" updates enrollment for "P001" to "C01" with status "ACCEPTED" and metadata "ghi" + Then expect no error + And expect enrollment for "P001" to "C01" to be "ACCEPTED" with metadata "ghi" + And expect EventUpdateProjectEnrollment with properties + """ + { + "issuer": "I02", "project_id": "P001", "class_id": "C01", + "old_status": "PROJECT_ENROLLMENT_STATUS_CHANGES_REQUESTED", + "new_status": "PROJECT_ENROLLMENT_STATUS_ACCEPTED", + "new_enrollment_metadata": "ghi" + } + """ diff --git a/x/ecocredit/base/keeper/features/msg_update_project_fee.feature b/x/ecocredit/base/keeper/features/msg_update_project_fee.feature new file mode 100644 index 0000000000..88c6d60730 --- /dev/null +++ b/x/ecocredit/base/keeper/features/msg_update_project_fee.feature @@ -0,0 +1,16 @@ +Feature: Msg/UpdateProjectFee + Rule: the authority can update the project fee + Scenario Outline: + Given current fee "" + When "" updates the fee to "" + Then expect error contains "" + And expect project fee is "" + Examples: + | scenario | authority | cur_fee | new_fee | expected_fee | err | + | gov creates | gov | | 200 | 200 | | + | gov updates | gov | 100 | 200 | 200 | | + | gov sets zero | gov | 100 | 0 | | | + | gov sets empty | gov | 100 | | | | + | bob creates | bob | | 200 | | invalid authority | + | bob updates | bob | 100 | 200 | 100 | invalid authority | + | bob sets zero | bob | 100 | 0 | 100 | invalid authority | diff --git a/x/ecocredit/base/keeper/fees.go b/x/ecocredit/base/keeper/fees.go new file mode 100644 index 0000000000..17d1db40ea --- /dev/null +++ b/x/ecocredit/base/keeper/fees.go @@ -0,0 +1,87 @@ +package keeper + +import ( + "context" + + basev1beta1 "github.com/cosmos/cosmos-sdk/api/cosmos/base/v1beta1" + "github.com/cosmos/cosmos-sdk/orm/types/ormerrors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + regentypes "github.com/regen-network/regen-ledger/types/v2" + "github.com/regen-network/regen-ledger/x/ecocredit/v3" +) + +func (k Keeper) deductFee(ctx context.Context, payer sdk.AccAddress, fee *sdk.Coin, minFee *basev1beta1.Coin) error { + if minFee == nil { + return nil + } + + requiredFee, ok := regentypes.ProtoCoinToCoin(minFee) + if !ok { + return sdkerrors.ErrInvalidType.Wrap("fee") + } + + if requiredFee.IsZero() { + return nil + } + + // check if fee is empty + if fee == nil { + return sdkerrors.ErrInsufficientFee.Wrapf( + "fee cannot be empty: must be %s", requiredFee, + ) + } + + // check if fee is the correct denom + if fee.Denom != requiredFee.Denom { + return sdkerrors.ErrInsufficientFee.Wrapf( + "fee must be %s, got %s", requiredFee, fee, + ) + } + + // check if fee is greater than or equal to required fee + if !fee.IsGTE(requiredFee) { + return sdkerrors.ErrInsufficientFee.Wrapf( + "fee must be %s, got %s", requiredFee, fee, + ) + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + // check payer balance against required fee + payerBalance := k.bankKeeper.GetBalance(sdkCtx, payer, requiredFee.Denom) + if payerBalance.IsNil() || payerBalance.IsLT(requiredFee) { + return sdkerrors.ErrInsufficientFunds.Wrapf( + "insufficient balance %s for bank denom %s", payerBalance.Amount, requiredFee.Denom, + ) + } + + feeCoins := sdk.Coins{requiredFee} + + err := k.bankKeeper.SendCoinsFromAccountToModule(sdkCtx, payer, ecocredit.ModuleName, feeCoins) + if err != nil { + return err + } + + if requiredFee.Denom == "uregen" { + err = k.bankKeeper.BurnCoins(sdkCtx, ecocredit.ModuleName, feeCoins) + if err != nil { + return err + } + } + + return nil +} + +func (k Keeper) deductCreateProjectFee(ctx context.Context, address sdk.AccAddress, fee *sdk.Coin) error { + projectFee, err := k.stateStore.ProjectFeeTable().Get(ctx) + if ormerrors.IsNotFound(err) { + // no fee set, so no fee to deduct + return nil + } + if err != nil { + return err + } + + return k.deductFee(ctx, address, fee, projectFee.Fee) +} diff --git a/x/ecocredit/base/keeper/keeper.go b/x/ecocredit/base/keeper/keeper.go index 4817597e39..f2214c2e32 100644 --- a/x/ecocredit/base/keeper/keeper.go +++ b/x/ecocredit/base/keeper/keeper.go @@ -16,9 +16,6 @@ var ( ) type Keeper struct { - *types.UnimplementedMsgServer - *types.UnimplementedQueryServer - stateStore api.StateStore bankKeeper ecocredit.BankKeeper moduleAddress sdk.AccAddress diff --git a/x/ecocredit/base/keeper/keeper_test.go b/x/ecocredit/base/keeper/keeper_test.go index 127640f8bb..a05b7c3da1 100644 --- a/x/ecocredit/base/keeper/keeper_test.go +++ b/x/ecocredit/base/keeper/keeper_test.go @@ -44,6 +44,7 @@ type baseSuite struct { ctrl *gomock.Controller addr sdk.AccAddress addr2 sdk.AccAddress + addr3 sdk.AccAddress bankKeeper *mocks.MockBankKeeper storeKey *storetypes.KVStoreKey sdkCtx sdk.Context @@ -86,6 +87,7 @@ func setupBase(t gocuke.TestingT) *baseSuite { s.k = NewKeeper(s.stateStore, s.bankKeeper, moduleAddress, basketStore, marketStore, s.authority) _, _, s.addr = testdata.KeyTestPubAddr() _, _, s.addr2 = testdata.KeyTestPubAddr() + _, _, s.addr3 = testdata.KeyTestPubAddr() return s } diff --git a/x/ecocredit/base/keeper/msg_bridge_receive.go b/x/ecocredit/base/keeper/msg_bridge_receive.go index a5db399fc9..2fb5b6e851 100644 --- a/x/ecocredit/base/keeper/msg_bridge_receive.go +++ b/x/ecocredit/base/keeper/msg_bridge_receive.go @@ -122,6 +122,7 @@ func (k Keeper) BridgeReceive(ctx context.Context, req *types.MsgBridgeReceive) batchRes, err := k.CreateBatch(ctx, &types.MsgCreateBatch{ Issuer: req.Issuer, ProjectId: project.Id, + ClassId: req.ClassId, Issuance: []*types.BatchIssuance{ { Recipient: req.Batch.Recipient, diff --git a/x/ecocredit/base/keeper/msg_bridge_receive_test.go b/x/ecocredit/base/keeper/msg_bridge_receive_test.go index 4c6fe289f2..650c65695a 100644 --- a/x/ecocredit/base/keeper/msg_bridge_receive_test.go +++ b/x/ecocredit/base/keeper/msg_bridge_receive_test.go @@ -17,7 +17,6 @@ import ( api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" regentypes "github.com/regen-network/regen-ledger/types/v2" "github.com/regen-network/regen-ledger/types/v2/testutil" - "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" ) @@ -99,16 +98,7 @@ func (s *bridgeReceiveSuite) ACreditClassWithIdAndIssuerAlice(a string) { func (s *bridgeReceiveSuite) AProjectWithId(a string) { pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: a, - ClassKey: s.classKey, - }) - require.NoError(s.t, err) - - seq := s.getProjectSequence(a) - - err = s.k.stateStore.ProjectSequenceTable().Insert(s.ctx, &api.ProjectSequence{ - ClassKey: s.classKey, - NextSequence: seq + 1, + Id: a, }) require.NoError(s.t, err) @@ -123,25 +113,13 @@ func (s *bridgeReceiveSuite) AProjectWithIdAndReferenceId(a, b string) { }) require.NoError(s.t, err) - seq := s.getProjectSequence(a) - - err = s.k.stateStore.ProjectSequenceTable().Insert(s.ctx, &api.ProjectSequence{ - ClassKey: s.classKey, - NextSequence: seq + 1, - }) - require.NoError(s.t, err) - s.projectKey = pKey } func (s *bridgeReceiveSuite) ACreditBatchWithDenomAndIssuerAlice(a string) { - projectID := base.GetProjectIDFromBatchDenom(a) - - project, err := s.k.stateStore.ProjectTable().GetById(s.ctx, projectID) - require.NoError(s.t, err) - bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ - ProjectKey: project.Key, + ProjectKey: s.projectKey, + ClassKey: s.classKey, Issuer: s.alice, Denom: a, Open: true, // always true unless specified @@ -151,7 +129,7 @@ func (s *bridgeReceiveSuite) ACreditBatchWithDenomAndIssuerAlice(a string) { seq := s.getBatchSequence(a) err = s.k.stateStore.BatchSequenceTable().Insert(s.ctx, &api.BatchSequence{ - ProjectKey: project.Key, + ProjectKey: s.projectKey, NextSequence: seq + 1, }) require.NoError(s.t, err) @@ -502,13 +480,6 @@ func (s *bridgeReceiveSuite) ExpectEventWithProperties(a gocuke.DocString) { require.NoError(s.t, err) } -func (s *bridgeReceiveSuite) getProjectSequence(projectID string) uint64 { - str := strings.Split(projectID, "-") - seq, err := strconv.ParseUint(str[1], 10, 32) - require.NoError(s.t, err) - return seq -} - func (s *bridgeReceiveSuite) getBatchSequence(batchDenom string) uint64 { str := strings.Split(batchDenom, "-") seq, err := strconv.ParseUint(str[4], 10, 32) diff --git a/x/ecocredit/base/keeper/msg_bridge_test.go b/x/ecocredit/base/keeper/msg_bridge_test.go index 8c02efcf22..0c0669e0cb 100644 --- a/x/ecocredit/base/keeper/msg_bridge_test.go +++ b/x/ecocredit/base/keeper/msg_bridge_test.go @@ -209,13 +209,13 @@ func (s *bridgeSuite) creditBatchSetup() { s.classKey = cKey pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: s.projectID, - ClassKey: cKey, + Id: s.projectID, }) require.NoError(s.t, err) bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: pKey, + ClassKey: s.classKey, Denom: s.batchDenom, }) require.NoError(s.t, err) diff --git a/x/ecocredit/base/keeper/msg_burn_regen.go b/x/ecocredit/base/keeper/msg_burn_regen.go index 0e33658e67..e51215aaf8 100644 --- a/x/ecocredit/base/keeper/msg_burn_regen.go +++ b/x/ecocredit/base/keeper/msg_burn_regen.go @@ -5,6 +5,7 @@ import ( "fmt" "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/regen-network/regen-ledger/x/ecocredit/v3" diff --git a/x/ecocredit/base/keeper/msg_burn_regen_test.go b/x/ecocredit/base/keeper/msg_burn_regen_test.go index def6f211af..d78aa5d3ea 100644 --- a/x/ecocredit/base/keeper/msg_burn_regen_test.go +++ b/x/ecocredit/base/keeper/msg_burn_regen_test.go @@ -3,11 +3,12 @@ package keeper import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gogo/protobuf/jsonpb" "github.com/regen-network/gocuke" "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/regen-network/regen-ledger/types/v2/testutil" "github.com/regen-network/regen-ledger/x/ecocredit/v3" types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" diff --git a/x/ecocredit/base/keeper/msg_cancel.go b/x/ecocredit/base/keeper/msg_cancel.go index cdb3beda0e..08bf05abc6 100644 --- a/x/ecocredit/base/keeper/msg_cancel.go +++ b/x/ecocredit/base/keeper/msg_cancel.go @@ -26,7 +26,7 @@ func (k Keeper) Cancel(ctx context.Context, req *types.MsgCancel) (*types.MsgCan if err != nil { return nil, sdkerrors.ErrInvalidRequest.Wrapf("could not get batch with denom %s: %s", credit.BatchDenom, err.Error()) } - creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch.Denom) + creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch) if err != nil { return nil, err } diff --git a/x/ecocredit/base/keeper/msg_cancel_test.go b/x/ecocredit/base/keeper/msg_cancel_test.go index b940956d00..76490a9cf6 100644 --- a/x/ecocredit/base/keeper/msg_cancel_test.go +++ b/x/ecocredit/base/keeper/msg_cancel_test.go @@ -68,6 +68,7 @@ func (s *cancel) ACreditBatchWithDenom(a string) { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: a, }) require.NoError(s.t, err) @@ -93,8 +94,7 @@ func (s *cancel) ACreditBatchFromCreditClassWithCreditType(a string) { s.classKey = cKey pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: s.projectID, - ClassKey: cKey, + Id: s.projectID, }) require.NoError(s.t, err) @@ -102,6 +102,7 @@ func (s *cancel) ACreditBatchFromCreditClassWithCreditType(a string) { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: s.batchDenom, }) require.NoError(s.t, err) @@ -235,8 +236,7 @@ func (s *cancel) projectSetup() { s.classKey = cKey pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: s.projectID, - ClassKey: cKey, + Id: s.projectID, }) require.NoError(s.t, err) @@ -248,6 +248,7 @@ func (s *cancel) creditBatchSetup() { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: s.batchDenom, }) require.NoError(s.t, err) diff --git a/x/ecocredit/base/keeper/msg_create_batch.go b/x/ecocredit/base/keeper/msg_create_batch.go index 2d53b65406..02fbe823c4 100644 --- a/x/ecocredit/base/keeper/msg_create_batch.go +++ b/x/ecocredit/base/keeper/msg_create_batch.go @@ -27,11 +27,22 @@ func (k Keeper) CreateBatch(ctx context.Context, req *types.MsgCreateBatch) (*ty return nil, sdkerrors.ErrInvalidRequest.Wrapf("could not get project with id %s: %s", req.ProjectId, err.Error()) } - class, err := k.stateStore.ClassTable().Get(ctx, project.ClassKey) + class, err := k.stateStore.ClassTable().GetById(ctx, req.ClassId) if err != nil { return nil, err } + // check if project enrollment exists + enrollment, err := k.stateStore.ProjectEnrollmentTable().Get(ctx, project.Key, class.Key) + if err != nil { + return nil, err + } + + // check if project enrollment is accepted + if enrollment.Status != api.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED { + return nil, sdkerrors.ErrInvalidRequest.Wrapf("project enrollment status is not accepted") + } + issuer, err := sdk.AccAddressFromBech32(req.Issuer) if err != nil { return nil, err @@ -47,7 +58,7 @@ func (k Keeper) CreateBatch(ctx context.Context, req *types.MsgCreateBatch) (*ty return nil, err } - batchDenom, err := base.FormatBatchDenom(project.Id, batchSeqNo, req.StartDate, req.EndDate) + batchDenom, err := base.FormatBatchDenom(class.Id, project.Id, batchSeqNo, req.StartDate, req.EndDate) if err != nil { return nil, err } @@ -63,6 +74,7 @@ func (k Keeper) CreateBatch(ctx context.Context, req *types.MsgCreateBatch) (*ty EndDate: endDate, IssuanceDate: issuanceDate, Open: req.Open, + ClassKey: class.Key, }) if err != nil { return nil, err @@ -193,7 +205,7 @@ func (k Keeper) CreateBatch(ctx context.Context, req *types.MsgCreateBatch) (*ty if req.OriginTx != nil { if err = k.stateStore.OriginTxIndexTable().Insert(ctx, &api.OriginTxIndex{ - ClassKey: project.ClassKey, + ClassKey: class.Key, Id: req.OriginTx.Id, Source: req.OriginTx.Source, }); err != nil { @@ -209,7 +221,7 @@ func (k Keeper) CreateBatch(ctx context.Context, req *types.MsgCreateBatch) (*ty if len(req.OriginTx.Contract) != 0 { err = k.stateStore.BatchContractTable().Insert(ctx, &api.BatchContract{ BatchKey: batchKey, - ClassKey: project.ClassKey, + ClassKey: class.Key, Contract: req.OriginTx.Contract, }) if err != nil { diff --git a/x/ecocredit/base/keeper/msg_create_batch_test.go b/x/ecocredit/base/keeper/msg_create_batch_test.go index 859ddd5b89..0ec534f316 100644 --- a/x/ecocredit/base/keeper/msg_create_batch_test.go +++ b/x/ecocredit/base/keeper/msg_create_batch_test.go @@ -4,7 +4,6 @@ package keeper import ( "encoding/json" "strconv" - "strings" "testing" "time" @@ -120,28 +119,23 @@ func (s *createBatchSuite) ACreditClassWithClassIdAndIssuerAlice(a string) { s.classKey = cKey } -func (s *createBatchSuite) AProjectWithProjectId(a string) { - classID := base.GetClassIDFromProjectID(a) - - class, err := s.k.stateStore.ClassTable().GetById(s.ctx, classID) - require.NoError(s.t, err) - +func (s *createBatchSuite) AProjectWithProjectIdEnrolledIn(a, b string) { pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: a, - ClassKey: class.Key, + Id: a, }) require.NoError(s.t, err) - seq := s.getProjectSequence(a) + s.projectKey = pKey - // Save because project sequence may already exist - err = s.k.stateStore.ProjectSequenceTable().Save(s.ctx, &api.ProjectSequence{ - ClassKey: class.Key, - NextSequence: seq + 1, - }) + cls, err := s.k.stateStore.ClassTable().GetById(s.ctx, b) require.NoError(s.t, err) - s.projectKey = pKey + err = s.k.stateStore.ProjectEnrollmentTable().Insert(s.ctx, &api.ProjectEnrollment{ + ProjectKey: pKey, + ClassKey: cls.Key, + Status: api.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + require.NoError(s.t, err) } func (s *createBatchSuite) ABatchSequenceWithProjectIdAndNextSequence(a string, b string) { @@ -189,10 +183,11 @@ func (s *createBatchSuite) OriginTx(a gocuke.DocString) { s.originTx = &ot } -func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectId(a string) { +func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndClassId(a, b string) { s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { Recipient: s.bob.String(), @@ -204,10 +199,11 @@ func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectId(a string) { }) } -func (s *createBatchSuite) BobAttemptsToCreateABatchWithProjectId(a string) { +func (s *createBatchSuite) BobAttemptsToCreateABatchWithProjectIdAndClassId(a, b string) { s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.bob.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { Recipient: s.alice.String(), @@ -219,35 +215,15 @@ func (s *createBatchSuite) BobAttemptsToCreateABatchWithProjectId(a string) { }) } -func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdStartDateAndEndDate(a, b, c string) { - startDate, err := regentypes.ParseDate("start date", b) - require.NoError(s.t, err) - - endDate, err := regentypes.ParseDate("end date", c) - require.NoError(s.t, err) - +func (s *createBatchSuite) AliceAttemptsToCreateABatchForProjectAndClassWithTradableAmount(a, b, c string) { s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { Recipient: s.bob.String(), - TradableAmount: s.tradableAmount, - }, - }, - StartDate: &startDate, - EndDate: &endDate, - }) -} - -func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndTradableAmount(a, b string) { - s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ - Issuer: s.alice.String(), - ProjectId: a, - Issuance: []*types.BatchIssuance{ - { - Recipient: s.bob.String(), - TradableAmount: b, + TradableAmount: c, }, }, StartDate: s.startDate, @@ -255,14 +231,15 @@ func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndTradableAm }) } -func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndRetiredAmount(a, b string) { +func (s *createBatchSuite) AliceAttemptsToCreateABatchForProjectAndClassWithRetiredAmount(a, b, c string) { s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { Recipient: s.bob.String(), - RetiredAmount: b, + RetiredAmount: c, }, }, StartDate: s.startDate, @@ -270,14 +247,15 @@ func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndRetiredAmo }) } -func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndOriginTx(a string, b gocuke.DocString) { +func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectClassAndOriginTx(a, b string, c gocuke.DocString) { var originTx types.OriginTx - err := jsonpb.UnmarshalString(b.Content, &originTx) + err := jsonpb.UnmarshalString(c.Content, &originTx) require.NoError(s.t, err) s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { Recipient: s.bob.String(), @@ -290,15 +268,16 @@ func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndOriginTx(a }) } -func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectIdAndIssuance(a string, b gocuke.DocString) { +func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProjectClassAndIssuance(a, b string, c gocuke.DocString) { var issuance []*types.BatchIssuance // unmarshal with json because issuance array is not a proto message - err := json.Unmarshal([]byte(b.Content), &issuance) + err := json.Unmarshal([]byte(c.Content), &issuance) require.NoError(s.t, err) s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: issuance, StartDate: s.startDate, EndDate: s.endDate, @@ -314,14 +293,15 @@ func (s *createBatchSuite) AliceAttemptsToCreateABatchWithProperties(a gocuke.Do s.res, s.err = s.k.CreateBatch(s.ctx, &msg) } -func (s *createBatchSuite) CreatesABatchFromProjectAndIssuesTradableCreditsTo(a string, b string, c string) { +func (s *createBatchSuite) CreatesABatchFromProjectClassAndIssuesTradableCreditsTo(a, b, c, d string) { s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { - Recipient: c, - TradableAmount: b, + Recipient: d, + TradableAmount: c, }, }, StartDate: s.startDate, @@ -331,15 +311,16 @@ func (s *createBatchSuite) CreatesABatchFromProjectAndIssuesTradableCreditsTo(a require.NoError(s.t, s.err) } -func (s *createBatchSuite) CreatesABatchFromProjectAndIssuesRetiredCreditsToFrom(a, b, c, d string) { +func (s *createBatchSuite) CreatesABatchFromProjectClassAndIssuesRetiredCreditsToFrom(a, b, c, d, e string) { s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { - Recipient: c, - RetiredAmount: b, - RetirementJurisdiction: d, + Recipient: d, + RetiredAmount: c, + RetirementJurisdiction: e, }, }, StartDate: s.startDate, @@ -349,16 +330,17 @@ func (s *createBatchSuite) CreatesABatchFromProjectAndIssuesRetiredCreditsToFrom require.NoError(s.t, s.err) } -func (s *createBatchSuite) CreatesABatchFromProjectAndIssuesRetiredCreditsToFromWithReason(a, b, c, d, e string) { +func (s *createBatchSuite) CreatesABatchFromProjectClassAndIssuesRetiredCreditsToFromWithReason(a, b, c, d, e, f string) { s.res, s.err = s.k.CreateBatch(s.ctx, &types.MsgCreateBatch{ Issuer: s.alice.String(), ProjectId: a, + ClassId: b, Issuance: []*types.BatchIssuance{ { - Recipient: c, - RetiredAmount: b, - RetirementJurisdiction: d, - RetirementReason: e, + Recipient: d, + RetiredAmount: c, + RetirementJurisdiction: e, + RetirementReason: f, }, }, StartDate: s.startDate, @@ -514,10 +496,3 @@ func (s *createBatchSuite) ExpectEventCreateBatchWithProperties(a gocuke.DocStri err = testutil.MatchEvent(&event, sdkEvent) require.NoError(s.t, err) } - -func (s *createBatchSuite) getProjectSequence(projectID string) uint64 { - str := strings.Split(projectID, "-") - seq, err := strconv.ParseUint(str[1], 10, 32) - require.NoError(s.t, err) - return seq -} diff --git a/x/ecocredit/base/keeper/msg_create_class.go b/x/ecocredit/base/keeper/msg_create_class.go index ed33bf619f..17538390f9 100644 --- a/x/ecocredit/base/keeper/msg_create_class.go +++ b/x/ecocredit/base/keeper/msg_create_class.go @@ -8,7 +8,6 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" - regentypes "github.com/regen-network/regen-ledger/types/v2" "github.com/regen-network/regen-ledger/x/ecocredit/v3" "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" @@ -35,51 +34,9 @@ func (k Keeper) CreateClass(goCtx context.Context, req *types.MsgCreateClass) (* return nil, err } - // only check and charge fee if required fee is set - if classFee.Fee != nil { - - requiredFee, ok := regentypes.ProtoCoinToCoin(classFee.Fee) - if !ok { - return nil, sdkerrors.ErrInvalidType.Wrap("class fee") - } - - // check if fee is empty - if req.Fee == nil { - return nil, sdkerrors.ErrInsufficientFee.Wrapf( - "fee cannot be empty: must be %s", requiredFee, - ) - } - - // check if fee is the correct denom - if req.Fee.Denom != requiredFee.Denom { - return nil, sdkerrors.ErrInsufficientFee.Wrapf( - "fee must be %s, got %s", requiredFee, req.Fee, - ) - } - - // check if fee is greater than or equal to required fee - if !req.Fee.IsGTE(requiredFee) { - return nil, sdkerrors.ErrInsufficientFee.Wrapf( - "fee must be %s, got %s", requiredFee, req.Fee, - ) - } - - // check admin balance against required fee - adminBalance := k.bankKeeper.GetBalance(sdkCtx, adminAddress, requiredFee.Denom) - if adminBalance.IsNil() || adminBalance.IsLT(requiredFee) { - return nil, sdkerrors.ErrInsufficientFunds.Wrapf( - "insufficient balance %s for bank denom %s", adminBalance.Amount, requiredFee.Denom, - ) - } - - // convert required fee to multiple coins for processing - requiredFees := sdk.Coins{requiredFee} - - // send coins from account to module and then burn the coins - err = k.chargeCreditClassFee(sdkCtx, adminAddress, requiredFees) - if err != nil { - return nil, err - } + err = k.deductFee(goCtx, adminAddress, req.Fee, classFee.Fee) + if err != nil { + return nil, err } creditType, err := k.stateStore.CreditTypeTable().Get(goCtx, req.CreditTypeAbbrev) @@ -159,18 +116,3 @@ func (k Keeper) assertCanCreateClass(ctx context.Context, adminAddress sdk.AccAd } return nil } - -func (k Keeper) chargeCreditClassFee(ctx sdk.Context, creatorAddr sdk.AccAddress, creditClassFee sdk.Coins) error { - // Move the fee to the ecocredit module's account - err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, creatorAddr, ecocredit.ModuleName, creditClassFee) - if err != nil { - return err - } - - err = k.bankKeeper.BurnCoins(ctx, ecocredit.ModuleName, creditClassFee) - if err != nil { - return err - } - - return nil -} diff --git a/x/ecocredit/base/keeper/msg_create_or_update_application.go b/x/ecocredit/base/keeper/msg_create_or_update_application.go new file mode 100644 index 0000000000..3e0905ba11 --- /dev/null +++ b/x/ecocredit/base/keeper/msg_create_or_update_application.go @@ -0,0 +1,76 @@ +package keeper + +import ( + "bytes" + "context" + + "github.com/cosmos/cosmos-sdk/orm/types/ormerrors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + ecocreditv1 "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func (k Keeper) CreateOrUpdateApplication(ctx context.Context, msg *types.MsgCreateOrUpdateApplication) (*types.MsgCreateOrUpdateApplicationResponse, error) { + admin, err := sdk.AccAddressFromBech32(msg.ProjectAdmin) + if err != nil { + return nil, err + } + + proj, err := k.stateStore.ProjectTable().GetById(ctx, msg.ProjectId) + if err != nil { + return nil, err + } + + if !bytes.Equal(proj.Admin, admin) { + return nil, sdkerrors.ErrUnauthorized + } + + class, err := k.stateStore.ClassTable().GetById(ctx, msg.ClassId) + if err != nil { + return nil, err + } + + action := types.EventUpdateApplication_ACTION_UPDATE + enrollment, err := k.stateStore.ProjectEnrollmentTable().Get(ctx, proj.Key, class.Key) + if ormerrors.IsNotFound(err) { + if msg.Withdraw { + return nil, sdkerrors.ErrInvalidRequest.Wrapf("cannot withdraw non-existent application") + } + + action = types.EventUpdateApplication_ACTION_CREATE + enrollment = &ecocreditv1.ProjectEnrollment{ + ProjectKey: proj.Key, + ClassKey: class.Key, + Status: ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_UNSPECIFIED, + } + } else if err != nil { + return nil, err + } + + if msg.Withdraw { + action = types.EventUpdateApplication_ACTION_WITHDRAW + if err := k.stateStore.ProjectEnrollmentTable().Delete(ctx, enrollment); err != nil { + return nil, err + } + } else { + enrollment.ApplicationMetadata = msg.Metadata + + if err := k.stateStore.ProjectEnrollmentTable().Save(ctx, enrollment); err != nil { + return nil, err + } + } + + err = sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&types.EventUpdateApplication{ + ProjectId: proj.Id, + ClassId: class.Id, + Action: action, + NewApplicationMetadata: msg.Metadata, + }) + if err != nil { + return nil, err + } + + return &types.MsgCreateOrUpdateApplicationResponse{}, nil +} diff --git a/x/ecocredit/base/keeper/msg_create_or_update_application_test.go b/x/ecocredit/base/keeper/msg_create_or_update_application_test.go new file mode 100644 index 0000000000..91b43749e5 --- /dev/null +++ b/x/ecocredit/base/keeper/msg_create_or_update_application_test.go @@ -0,0 +1,125 @@ +package keeper + +import ( + "testing" + + "github.com/gogo/protobuf/jsonpb" + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/orm/types/ormerrors" + sdk "github.com/cosmos/cosmos-sdk/types" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + "github.com/regen-network/regen-ledger/types/v2/testutil" + v1 "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +type createOrUpdateApplicationSuite struct { + *baseSuite + addrs map[string]sdk.AccAddress + err error +} + +func TestCreateOrUpdateApplication(t *testing.T) { + gocuke.NewRunner(t, &createOrUpdateApplicationSuite{}). + Path("./features/msg_create_or_update_application.feature"). + Run() +} + +func (s *createOrUpdateApplicationSuite) Before(t gocuke.TestingT) { + s.baseSuite = setupBase(t) + s.addrs = make(map[string]sdk.AccAddress) + s.addrs["Alice"] = s.addr + s.addrs["Bob"] = s.addr2 +} + +func (s *createOrUpdateApplicationSuite) ProjectWithAdmin(projId, admin string) { + require.NoError(s.t, s.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ + Id: projId, + Admin: s.addrs[admin], + })) +} + +func (s *createOrUpdateApplicationSuite) CreditClass(clsId string) { + require.NoError(s.t, s.stateStore.ClassTable().Insert(s.ctx, &api.Class{ + Id: clsId, + })) +} + +func (s *createOrUpdateApplicationSuite) AnApplicationForToWithMetadata(projId, clsId, metadata string) { + proj, err := s.stateStore.ProjectTable().GetById(s.ctx, projId) + require.NoError(s.t, err) + cls, err := s.stateStore.ClassTable().GetById(s.ctx, clsId) + require.NoError(s.t, err) + require.NoError(s.t, s.stateStore.ProjectEnrollmentTable().Insert(s.ctx, &api.ProjectEnrollment{ + ProjectKey: proj.Key, + ClassKey: cls.Key, + ApplicationMetadata: metadata, + })) +} + +func (s *createOrUpdateApplicationSuite) AnApplicationForToDoesNotExist(projId, clsId string) { + enrollment, err := s.getEnrollment(projId, clsId) + if !ormerrors.IsNotFound(err) { + s.t.Fatalf("expected project enrollment not found, got %v", enrollment) + } +} + +func (s *createOrUpdateApplicationSuite) CreatesOrUpdatesAnApplicationForToWithMetadata(admin, projId, clsId, metadata string) { + _, s.err = s.k.CreateOrUpdateApplication(s.ctx, &v1.MsgCreateOrUpdateApplication{ + ProjectAdmin: s.addrs[admin].String(), + ProjectId: projId, + ClassId: clsId, + Metadata: metadata, + Withdraw: false, + }) +} + +func (s *createOrUpdateApplicationSuite) AttemptsToWithdrawTheApplicationForToWithMetadata(admin, projId, clsId, metadata string) { + _, s.err = s.k.CreateOrUpdateApplication(s.ctx, &v1.MsgCreateOrUpdateApplication{ + ProjectAdmin: s.addrs[admin].String(), + ProjectId: projId, + ClassId: clsId, + Metadata: metadata, + Withdraw: true, + }) +} + +func (s *createOrUpdateApplicationSuite) ExpectNoError() { + require.NoError(s.t, s.err) +} + +func (s *createOrUpdateApplicationSuite) ExpectErrorContains(x string) { + if x == "" { + require.NoError(s.t, s.err) + } else { + require.ErrorContains(s.t, s.err, x) + } +} + +func (s *createOrUpdateApplicationSuite) ExpectTheApplicationForToExistsWithMetadata(projId, clsId, metadata string) { + enrollment, err := s.getEnrollment(projId, clsId) + require.NoError(s.t, err) + require.Equal(s.t, metadata, enrollment.ApplicationMetadata) +} + +func (s *createOrUpdateApplicationSuite) ExpectEventupdateapplicationWithProperties(a gocuke.DocString) { + var evtExpected v1.EventUpdateApplication + err := jsonpb.UnmarshalString(a.Content, &evtExpected) + require.NoError(s.t, err) + + evtActual, found := testutil.GetEvent(&evtExpected, s.sdkCtx.EventManager().Events()) + require.True(s.t, found) + + err = testutil.MatchEvent(&evtExpected, evtActual) + require.NoError(s.t, err) +} + +func (s *createOrUpdateApplicationSuite) getEnrollment(projId, clsId string) (*api.ProjectEnrollment, error) { + proj, err := s.stateStore.ProjectTable().GetById(s.ctx, projId) + require.NoError(s.t, err) + cls, err := s.stateStore.ClassTable().GetById(s.ctx, clsId) + require.NoError(s.t, err) + return s.stateStore.ProjectEnrollmentTable().Get(s.ctx, proj.Key, cls.Key) +} diff --git a/x/ecocredit/base/keeper/msg_create_project.go b/x/ecocredit/base/keeper/msg_create_project.go index 7085d1d277..c7f8daec74 100644 --- a/x/ecocredit/base/keeper/msg_create_project.go +++ b/x/ecocredit/base/keeper/msg_create_project.go @@ -3,7 +3,6 @@ package keeper import ( "context" - "github.com/cosmos/cosmos-sdk/orm/types/ormerrors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -25,12 +24,17 @@ func (k Keeper) CreateProject(ctx context.Context, req *types.MsgCreateProject) return nil, err } + err = k.deductCreateProjectFee(ctx, adminAddress, req.Fee) + if err != nil { + return nil, err + } + err = k.assertClassIssuer(ctx, classInfo.Key, adminAddress) if err != nil { return nil, err } - projectID, err := k.genProjectID(ctx, classInfo.Key, classInfo.Id) + project, projectID, err := k.createNewProject(ctx) if err != nil { return nil, err } @@ -41,14 +45,26 @@ func (k Keeper) CreateProject(ctx context.Context, req *types.MsgCreateProject) return nil, err } - if err = k.stateStore.ProjectTable().Insert(ctx, &api.Project{ - Id: projectID, - Admin: adminAddress, - ClassKey: classInfo.Key, - Jurisdiction: req.Jurisdiction, - Metadata: req.Metadata, - ReferenceId: req.ReferenceId, - }); err != nil { + project.Admin = adminAddress + project.Jurisdiction = req.Jurisdiction + project.Metadata = req.Metadata + if req.ReferenceId != "" { + project.ReferenceId = req.ReferenceId + // only set deprecated class key if reference id is not empty to support the use case of reference IDs + project.ClassKey = classInfo.Key //nolint:staticcheck + } + + if err = k.stateStore.ProjectTable().Save(ctx, project); err != nil { + return nil, err + } + + // create enrollment + enrollment := &api.ProjectEnrollment{ + ProjectKey: project.Key, + ClassKey: classInfo.Key, + Status: api.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + } + if err = k.stateStore.ProjectEnrollmentTable().Insert(ctx, enrollment); err != nil { return nil, err } @@ -63,28 +79,23 @@ func (k Keeper) CreateProject(ctx context.Context, req *types.MsgCreateProject) }, nil } -// genProjectID generates a projectID when no projectID was given for CreateProject. +// createNewProject generates a projectID when no projectID was given for CreateProject. // The ID is generated by concatenating the classID and a sequence number. -func (k Keeper) genProjectID(ctx context.Context, classKey uint64, classID string) (string, error) { - var nextSeq uint64 - projectSeqNo, err := k.stateStore.ProjectSequenceTable().Get(ctx, classKey) - switch err { - case ormerrors.NotFound: - nextSeq = 1 - case nil: - nextSeq = projectSeqNo.NextSequence - default: - return "", err - } - - if err = k.stateStore.ProjectSequenceTable().Save(ctx, &api.ProjectSequence{ - ClassKey: classKey, - NextSequence: nextSeq + 1, - }); err != nil { - return "", err +func (k Keeper) createNewProject(ctx context.Context) (*api.Project, string, error) { + newProject := &api.Project{} + id, err := k.stateStore.ProjectTable().InsertReturningID(ctx, newProject) + if err != nil { + return nil, "", err + } + + projectID := base.FormatProjectID(id) + newProject.Id = projectID + err = k.stateStore.ProjectTable().Update(ctx, newProject) + if err != nil { + return nil, "", err } - return base.FormatProjectID(classID, nextSeq), nil + return newProject, projectID, nil } // verifyReferenceID prevents multiple projects from having the same reference id within the diff --git a/x/ecocredit/base/keeper/msg_create_project_test.go b/x/ecocredit/base/keeper/msg_create_project_test.go index d710aee945..91337a08c3 100644 --- a/x/ecocredit/base/keeper/msg_create_project_test.go +++ b/x/ecocredit/base/keeper/msg_create_project_test.go @@ -3,8 +3,6 @@ package keeper import ( "encoding/json" - "strconv" - "strings" "testing" "github.com/gogo/protobuf/jsonpb" @@ -61,39 +59,21 @@ func (s *createProjectSuite) ACreditClassWithClassIdAndIssuerAlice(a string) { require.NoError(s.t, err) } -func (s *createProjectSuite) AProjectSequenceWithClassIdAndNextSequence(a, b string) { - class, err := s.k.stateStore.ClassTable().GetById(s.ctx, a) - require.NoError(s.t, err) - - nextSequence, err := strconv.ParseUint(b, 10, 32) - require.NoError(s.t, err) - - err = s.k.stateStore.ProjectSequenceTable().Insert(s.ctx, &api.ProjectSequence{ - ClassKey: class.Key, - NextSequence: nextSequence, - }) - require.NoError(s.t, err) -} - -func (s *createProjectSuite) AProjectWithProjectIdAndReferenceId(a, b string) { - classID := base.GetClassIDFromProjectID(a) - - class, err := s.k.stateStore.ClassTable().GetById(s.ctx, classID) +func (s *createProjectSuite) AProjectInClassWithReferenceId(projId, clsId, refId string) { + cls, err := s.k.stateStore.ClassTable().GetById(s.ctx, clsId) require.NoError(s.t, err) err = s.k.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ - Id: a, - ClassKey: class.Key, - ReferenceId: b, + Id: projId, + ReferenceId: refId, + ClassKey: cls.Key, }) require.NoError(s.t, err) - seq := s.getProjectSequence(a) - - // Save because project sequence may already exist - err = s.k.stateStore.ProjectSequenceTable().Save(s.ctx, &api.ProjectSequence{ - ClassKey: class.Key, - NextSequence: seq + 1, + err = s.stateStore.ProjectEnrollmentTable().Insert(s.ctx, &api.ProjectEnrollment{ + ProjectKey: cls.Key, + ClassKey: cls.Key, + Status: api.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, }) require.NoError(s.t, err) } @@ -124,14 +104,10 @@ func (s *createProjectSuite) AliceAttemptsToCreateAProjectWithProperties(a gocuk var msg types.MsgCreateProject err := jsonpb.UnmarshalString(a.Content, &msg) require.NoError(s.t, err) + msg.Admin = s.alice.String() - s.res, s.err = s.k.CreateProject(s.ctx, &types.MsgCreateProject{ - Admin: s.alice.String(), - ClassId: msg.ClassId, - Metadata: msg.Metadata, - Jurisdiction: msg.Jurisdiction, - ReferenceId: msg.ReferenceId, - }) + s.res, s.err = s.k.CreateProject(s.ctx, &msg) + require.NoError(s.t, s.err) } func (s *createProjectSuite) ExpectNoError() { @@ -146,19 +122,6 @@ func (s *createProjectSuite) ExpectErrorContains(a string) { require.ErrorContains(s.t, s.err, a) } -func (s *createProjectSuite) ExpectProjectSequenceWithClassIdAndNextSequence(a string, b string) { - project, err := s.stateStore.ClassTable().GetById(s.ctx, a) - require.NoError(s.t, err) - - nextSequence, err := strconv.ParseUint(b, 10, 64) - require.NoError(s.t, err) - - projectSequence, err := s.stateStore.ProjectSequenceTable().Get(s.ctx, project.Key) - require.NoError(s.t, err) - - require.Equal(s.t, nextSequence, projectSequence.NextSequence) -} - func (s *createProjectSuite) ExpectProjectProperties(a gocuke.DocString) { var expected types.Project err := jsonpb.UnmarshalString(a.Content, &expected) @@ -191,10 +154,3 @@ func (s *createProjectSuite) ExpectEventWithProperties(a gocuke.DocString) { err = testutil.MatchEvent(&event, sdkEvent) require.NoError(s.t, err) } - -func (s *createProjectSuite) getProjectSequence(projectID string) uint64 { - str := strings.Split(projectID, "-") - seq, err := strconv.ParseUint(str[1], 10, 32) - require.NoError(s.t, err) - return seq -} diff --git a/x/ecocredit/base/keeper/msg_create_unregistered_project.go b/x/ecocredit/base/keeper/msg_create_unregistered_project.go new file mode 100644 index 0000000000..841ec37eb1 --- /dev/null +++ b/x/ecocredit/base/keeper/msg_create_unregistered_project.go @@ -0,0 +1,36 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func (k Keeper) CreateUnregisteredProject(ctx context.Context, msg *types.MsgCreateUnregisteredProject) (*types.MsgCreateUnregisteredProjectResponse, error) { + admin, err := sdk.AccAddressFromBech32(msg.Admin) + if err != nil { + return nil, err + } + + err = k.deductCreateProjectFee(ctx, admin, msg.Fee) + if err != nil { + return nil, err + } + + project, projectID, err := k.createNewProject(ctx) + if err != nil { + return nil, err + } + + project.Admin = admin + project.Jurisdiction = msg.Jurisdiction + project.Metadata = msg.Metadata + + if err = k.stateStore.ProjectTable().Save(ctx, project); err != nil { + return nil, err + } + + return &types.MsgCreateUnregisteredProjectResponse{ProjectId: projectID}, nil +} diff --git a/x/ecocredit/base/keeper/msg_create_unregistered_project_test.go b/x/ecocredit/base/keeper/msg_create_unregistered_project_test.go new file mode 100644 index 0000000000..bd8d6b312e --- /dev/null +++ b/x/ecocredit/base/keeper/msg_create_unregistered_project_test.go @@ -0,0 +1,103 @@ +package keeper + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" + + basev1beta1 "github.com/cosmos/cosmos-sdk/api/cosmos/base/v1beta1" + sdk "github.com/cosmos/cosmos-sdk/types" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + v1 "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +type createUnregisteredProjectSuite struct { + *baseSuite + err error + res *v1.MsgCreateUnregisteredProjectResponse + balance sdk.Coins +} + +func TestCreateUnregisteredProject(t *testing.T) { + gocuke.NewRunner(t, &createUnregisteredProjectSuite{}). + Path("./features/msg_create_unregistered_project.feature"). + Run() +} + +func (s *createUnregisteredProjectSuite) Before(t gocuke.TestingT) { + s.baseSuite = setupBase(t) + s.bankKeeper.EXPECT(). + GetBalance(gomock.Any(), s.addr, "regen"). + DoAndReturn(func(_ sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin { + if addr.Equals(s.addr) { + ok, denom := s.balance.Find(denom) + if ok { + return denom + } + } + return sdk.Coin{} + }). + AnyTimes() + + s.bankKeeper.EXPECT(). + SendCoinsFromAccountToModule(gomock.Any(), s.addr, gomock.Any(), gomock.Any()). + DoAndReturn(func(_ sdk.Context, fromAddr sdk.AccAddress, _ string, coins sdk.Coins) error { + if fromAddr.Equals(s.addr) { + s.balance = s.balance.Sub(coins...) + return nil + } + return fmt.Errorf("unexpected from address: %s", fromAddr) + }). + AnyTimes() +} + +func (s *createUnregisteredProjectSuite) ProjectCreationFee(fee string) { + coin, err := sdk.ParseCoinNormalized(fee) + require.NoError(s.t, err) + require.NoError(s.t, s.stateStore.ProjectFeeTable().Save(s.ctx, &api.ProjectFee{ + Fee: &basev1beta1.Coin{ + Denom: coin.Denom, + Amount: coin.Amount.String(), + }, + })) +} + +func (s *createUnregisteredProjectSuite) IHaveBalance(balance string) { + coins, err := sdk.ParseCoinsNormalized(balance) + require.NoError(s.t, err) + s.balance = coins +} + +func (s *createUnregisteredProjectSuite) ICreateAProjectWithJurisdictionAndFee(jurisdiction, fee string) { + coin, err := sdk.ParseCoinNormalized(fee) + require.NoError(s.t, err) + s.res, s.err = s.k.CreateUnregisteredProject(s.ctx, &v1.MsgCreateUnregisteredProject{ + Admin: s.addr.String(), + Jurisdiction: jurisdiction, + Fee: &coin, + }) +} + +func (s *createUnregisteredProjectSuite) ExpectTheProjectIsCreatedSuccessfully() { + require.NoError(s.t, s.err) + require.NotNil(s.t, s.res) + require.NotEmpty(s.t, s.res.ProjectId) +} + +func (s *createUnregisteredProjectSuite) ExpectBalance(a string) { + coins, err := sdk.ParseCoinsNormalized(a) + require.NoError(s.t, err) + require.True(s.t, s.balance.IsEqual(coins), "expected balance %s, got %s", coins, s.balance) +} + +func (s *createUnregisteredProjectSuite) ExpectErrorContains(x string) { + if x == "" { + require.NoError(s.t, s.err) + } else { + require.ErrorContains(s.t, s.err, x) + } +} diff --git a/x/ecocredit/base/keeper/msg_mint_batch_credits.go b/x/ecocredit/base/keeper/msg_mint_batch_credits.go index 03cbb304af..a5e5664008 100644 --- a/x/ecocredit/base/keeper/msg_mint_batch_credits.go +++ b/x/ecocredit/base/keeper/msg_mint_batch_credits.go @@ -28,13 +28,8 @@ func (k Keeper) MintBatchCredits(ctx context.Context, req *types.MsgMintBatchCre return nil, err } - project, err := k.stateStore.ProjectTable().Get(ctx, batch.ProjectKey) - if err != nil { - return nil, err - } - if err = k.stateStore.OriginTxIndexTable().Insert(ctx, &api.OriginTxIndex{ - ClassKey: project.ClassKey, + ClassKey: batch.ClassKey, Id: req.OriginTx.Id, Source: req.OriginTx.Source, }); err != nil { @@ -44,7 +39,7 @@ func (k Keeper) MintBatchCredits(ctx context.Context, req *types.MsgMintBatchCre return nil, err } - ct, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch.Denom) + ct, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch) if err != nil { return nil, err } diff --git a/x/ecocredit/base/keeper/msg_mint_batch_credits_test.go b/x/ecocredit/base/keeper/msg_mint_batch_credits_test.go index 176a0c08f4..38cfc00b86 100644 --- a/x/ecocredit/base/keeper/msg_mint_batch_credits_test.go +++ b/x/ecocredit/base/keeper/msg_mint_batch_credits_test.go @@ -15,7 +15,6 @@ import ( api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" "github.com/regen-network/regen-ledger/types/v2/testutil" - "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" ) @@ -75,8 +74,7 @@ func (s *mintBatchCredits) ACreditClassWithIdAndIssuerAlice(a string) { func (s *mintBatchCredits) AProjectWithId(a string) { pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: a, - ClassKey: s.classKey, + Id: a, }) require.NoError(s.t, err) @@ -84,13 +82,9 @@ func (s *mintBatchCredits) AProjectWithId(a string) { } func (s *mintBatchCredits) ACreditBatchWithDenomAndIssuerAlice(a string) { - projectID := base.GetProjectIDFromBatchDenom(a) - - project, err := s.k.stateStore.ProjectTable().GetById(s.ctx, projectID) - require.NoError(s.t, err) - bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ - ProjectKey: project.Key, + ProjectKey: s.projectKey, + ClassKey: s.classKey, Issuer: s.alice, Denom: a, Open: true, // always true unless specified @@ -116,6 +110,7 @@ func (s *mintBatchCredits) ACreditBatchWithDenomOpenAndIssuerAlice(a, b string) Issuer: s.alice, Denom: a, ProjectKey: s.projectKey, + ClassKey: s.classKey, Open: open, }) require.NoError(s.t, err) diff --git a/x/ecocredit/base/keeper/msg_retire.go b/x/ecocredit/base/keeper/msg_retire.go index be95f3e208..d0c8bcbaf4 100644 --- a/x/ecocredit/base/keeper/msg_retire.go +++ b/x/ecocredit/base/keeper/msg_retire.go @@ -24,7 +24,7 @@ func (k Keeper) Retire(ctx context.Context, req *types.MsgRetire) (*types.MsgRet if err != nil { return nil, sdkerrors.ErrInvalidRequest.Wrapf("could not get batch with denom %s: %s", credit.BatchDenom, err.Error()) } - creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch.Denom) + creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch) if err != nil { return nil, err } diff --git a/x/ecocredit/base/keeper/msg_retire_test.go b/x/ecocredit/base/keeper/msg_retire_test.go index 225058ea8e..bce31fb06a 100644 --- a/x/ecocredit/base/keeper/msg_retire_test.go +++ b/x/ecocredit/base/keeper/msg_retire_test.go @@ -67,6 +67,7 @@ func (s *retire) ACreditBatchWithDenom(a string) { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: a, }) require.NoError(s.t, err) @@ -98,8 +99,7 @@ func (s *retire) ACreditBatchFromCreditClassWithCreditType(a string) { s.classKey = cKey pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: s.projectID, - ClassKey: cKey, + Id: s.projectID, }) require.NoError(s.t, err) @@ -107,6 +107,7 @@ func (s *retire) ACreditBatchFromCreditClassWithCreditType(a string) { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: s.batchDenom, }) require.NoError(s.t, err) @@ -268,8 +269,7 @@ func (s *retire) projectSetup() { s.classKey = cKey pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: s.projectID, - ClassKey: cKey, + Id: s.projectID, }) require.NoError(s.t, err) @@ -281,6 +281,7 @@ func (s *retire) creditBatchSetup() { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: s.batchDenom, }) require.NoError(s.t, err) diff --git a/x/ecocredit/base/keeper/msg_seal_batch_test.go b/x/ecocredit/base/keeper/msg_seal_batch_test.go index 2e2957f357..71bcf2e12b 100644 --- a/x/ecocredit/base/keeper/msg_seal_batch_test.go +++ b/x/ecocredit/base/keeper/msg_seal_batch_test.go @@ -12,7 +12,6 @@ import ( api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" "github.com/regen-network/regen-ledger/types/v2/testutil" - "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" ) @@ -24,6 +23,7 @@ type sealBatch struct { classKey uint64 res *types.MsgSealBatchResponse err error + projectKey uint64 } func TestSealBatch(t *testing.T) { @@ -63,21 +63,17 @@ func (s *sealBatch) ACreditClassWithIdAndIssuerAlice(a string) { } func (s *sealBatch) AProjectWithId(a string) { - err := s.k.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ - Id: a, - ClassKey: s.classKey, + var err error + s.projectKey, err = s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ + Id: a, }) require.NoError(s.t, err) } func (s *sealBatch) ACreditBatchWithDenomAndIssuerAlice(a string) { - projectID := base.GetProjectIDFromBatchDenom(a) - - project, err := s.k.stateStore.ProjectTable().GetById(s.ctx, projectID) - require.NoError(s.t, err) - bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ - ProjectKey: project.Key, + ProjectKey: s.projectKey, + ClassKey: s.classKey, Issuer: s.alice, Denom: a, Open: true, diff --git a/x/ecocredit/base/keeper/msg_send.go b/x/ecocredit/base/keeper/msg_send.go index 2651079bd8..fda0779b33 100644 --- a/x/ecocredit/base/keeper/msg_send.go +++ b/x/ecocredit/base/keeper/msg_send.go @@ -32,7 +32,7 @@ func (k Keeper) Send(ctx context.Context, req *types.MsgSend) (*types.MsgSendRes } // get credit type precision - creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch.Denom) + creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.stateStore, batch) if err != nil { return nil, err } diff --git a/x/ecocredit/base/keeper/msg_send_test.go b/x/ecocredit/base/keeper/msg_send_test.go index e3079ac79c..89f8296c0a 100644 --- a/x/ecocredit/base/keeper/msg_send_test.go +++ b/x/ecocredit/base/keeper/msg_send_test.go @@ -69,6 +69,7 @@ func (s *send) ACreditBatchWithDenom(a string) { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: a, }) require.NoError(s.t, err) @@ -94,8 +95,7 @@ func (s *send) ACreditBatchFromCreditClassWithCreditType(a string) { s.classKey = cKey pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: s.projectID, - ClassKey: cKey, + Id: s.projectID, }) require.NoError(s.t, err) @@ -103,6 +103,7 @@ func (s *send) ACreditBatchFromCreditClassWithCreditType(a string) { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: s.batchDenom, }) require.NoError(s.t, err) @@ -344,8 +345,7 @@ func (s *send) projectSetup() { s.classKey = cKey pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: s.projectID, - ClassKey: cKey, + Id: s.projectID, }) require.NoError(s.t, err) @@ -357,6 +357,7 @@ func (s *send) creditBatchSetup() { bKey, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ ProjectKey: s.projectKey, + ClassKey: s.classKey, Denom: s.batchDenom, }) require.NoError(s.t, err) diff --git a/x/ecocredit/base/keeper/msg_update_batch_metadata_test.go b/x/ecocredit/base/keeper/msg_update_batch_metadata_test.go index e4bf697964..cee14c1e22 100644 --- a/x/ecocredit/base/keeper/msg_update_batch_metadata_test.go +++ b/x/ecocredit/base/keeper/msg_update_batch_metadata_test.go @@ -16,7 +16,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" - "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" ) @@ -68,8 +67,7 @@ func (s *updateBatchMetadata) ACreditClassWithIdAndIssuerAlice(a string) { func (s *updateBatchMetadata) AProjectWithId(a string) { pKey, err := s.k.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ - Id: a, - ClassKey: s.classKey, + Id: a, }) require.NoError(s.t, err) @@ -77,13 +75,9 @@ func (s *updateBatchMetadata) AProjectWithId(a string) { } func (s *updateBatchMetadata) ACreditBatchWithBatchDenomAndIssuerAlice(a string) { - projectID := base.GetProjectIDFromBatchDenom(a) - - project, err := s.k.stateStore.ProjectTable().GetById(s.ctx, projectID) - require.NoError(s.t, err) - - _, err = s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ - ProjectKey: project.Key, + _, err := s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ + ProjectKey: s.projectKey, + ClassKey: s.classKey, Issuer: s.alice, Denom: a, Open: true, // true unless specified @@ -94,16 +88,12 @@ func (s *updateBatchMetadata) ACreditBatchWithBatchDenomAndIssuerAlice(a string) } func (s *updateBatchMetadata) ACreditBatchWithBatchDenomIssuerAliceAndOpen(a, b string) { - projectID := base.GetProjectIDFromBatchDenom(a) - - project, err := s.k.stateStore.ProjectTable().GetById(s.ctx, projectID) - require.NoError(s.t, err) - open, err := strconv.ParseBool(b) require.NoError(s.t, err) _, err = s.k.stateStore.BatchTable().InsertReturningID(s.ctx, &api.Batch{ - ProjectKey: project.Key, + ProjectKey: s.projectKey, + ClassKey: s.classKey, Issuer: s.alice, Denom: a, Open: open, diff --git a/x/ecocredit/base/keeper/msg_update_project_enrollment.go b/x/ecocredit/base/keeper/msg_update_project_enrollment.go new file mode 100644 index 0000000000..e94e266420 --- /dev/null +++ b/x/ecocredit/base/keeper/msg_update_project_enrollment.go @@ -0,0 +1,93 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + ecocreditv1 "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func (k Keeper) UpdateProjectEnrollment(ctx context.Context, msg *types.MsgUpdateProjectEnrollment) (*types.MsgUpdateProjectEnrollmentResponse, error) { + issuer, err := sdk.AccAddressFromBech32(msg.Issuer) + if err != nil { + return nil, err + } + + class, err := k.stateStore.ClassTable().GetById(ctx, msg.ClassId) + if err != nil { + return nil, err + } + + err = k.assertClassIssuer(ctx, class.Key, issuer) + if err != nil { + return nil, err + } + + proj, err := k.stateStore.ProjectTable().GetById(ctx, msg.ProjectId) + if err != nil { + return nil, err + } + + enrollment, err := k.stateStore.ProjectEnrollmentTable().Get(ctx, proj.Key, class.Key) + if err != nil { + return nil, err + } + + existingStatus := enrollment.Status + newStatus := ecocreditv1.ProjectEnrollmentStatus(msg.NewStatus) + remove := false + switch existingStatus { + case ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_UNSPECIFIED, + ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_CHANGES_REQUESTED: + switch newStatus { + case ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_CHANGES_REQUESTED, + ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED: + // Valid case + case ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_REJECTED: + remove = true + default: + return nil, sdkerrors.ErrInvalidRequest.Wrapf("invalid status transition from %s to %s", existingStatus, newStatus) + } + case ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED: + switch newStatus { + case ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED: + // Valid case for just updating metadata of an accepted project + case ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_TERMINATED: + remove = true + default: + return nil, sdkerrors.ErrInvalidRequest.Wrapf("invalid status transition from %s to %s", existingStatus, newStatus) + } + default: + return nil, sdkerrors.ErrLogic.Wrapf("invalid existing status: %s", existingStatus) + } + + enrollment.Status = newStatus + enrollment.EnrollmentMetadata = msg.Metadata + + if remove { + if err := k.stateStore.ProjectEnrollmentTable().Delete(ctx, enrollment); err != nil { + return nil, err + } + + } else { + if err := k.stateStore.ProjectEnrollmentTable().Save(ctx, enrollment); err != nil { + return nil, err + } + } + + if err := sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&types.EventUpdateProjectEnrollment{ + Issuer: msg.Issuer, + ProjectId: proj.Id, + ClassId: class.Id, + OldStatus: types.ProjectEnrollmentStatus(existingStatus), + NewStatus: types.ProjectEnrollmentStatus(newStatus), + NewEnrollmentMetadata: msg.Metadata, + }); err != nil { + return nil, err + } + + return &types.MsgUpdateProjectEnrollmentResponse{}, nil +} diff --git a/x/ecocredit/base/keeper/msg_update_project_enrollment_test.go b/x/ecocredit/base/keeper/msg_update_project_enrollment_test.go new file mode 100644 index 0000000000..1bbf61d046 --- /dev/null +++ b/x/ecocredit/base/keeper/msg_update_project_enrollment_test.go @@ -0,0 +1,158 @@ +package keeper + +import ( + "fmt" + "testing" + + "github.com/gogo/protobuf/jsonpb" + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + + "github.com/cosmos/cosmos-sdk/orm/types/ormerrors" + sdk "github.com/cosmos/cosmos-sdk/types" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + "github.com/regen-network/regen-ledger/types/v2/testutil" + v1 "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +type updateProjectEnrollmentSuite struct { + *baseSuite + err error + addrs map[string]sdk.AccAddress +} + +func TestUpdateProjectEnrollment(t *testing.T) { + gocuke.NewRunner(t, &updateProjectEnrollmentSuite{}). + Path("./features/msg_update_project_enrollment.feature"). + Run() +} + +func (s *updateProjectEnrollmentSuite) Before(t gocuke.TestingT) { + s.baseSuite = setupBase(t) + s.addrs = map[string]sdk.AccAddress{ + "I01": s.addr, + "I02": s.addr2, + "Bob": s.addr3, + } +} + +func (s *updateProjectEnrollmentSuite) Project(projId string) { + err := s.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ + Id: projId, + }) + require.NoError(s.t, err) +} + +func (s *updateProjectEnrollmentSuite) Class(clsId string) { + err := s.stateStore.ClassTable().Insert(s.ctx, &api.Class{ + Id: clsId, + }) + require.NoError(s.t, err) +} + +func (s *updateProjectEnrollmentSuite) ClassIssuerFor(issuer, clsId string) { + cls, err := s.stateStore.ClassTable().GetById(s.ctx, clsId) + require.NoError(s.t, err) + err = s.stateStore.ClassIssuerTable().Insert(s.ctx, &api.ClassIssuer{ + ClassKey: cls.Key, + Issuer: s.addrs[issuer], + }) + require.NoError(s.t, err) +} + +func (s *updateProjectEnrollmentSuite) EnrollmentForToIsWithMetadata(projId, clsId, status, metadata string) { + proj, err := s.stateStore.ProjectTable().GetById(s.ctx, projId) + require.NoError(s.t, err) + cls, err := s.stateStore.ClassTable().GetById(s.ctx, clsId) + require.NoError(s.t, err) + err = s.stateStore.ProjectEnrollmentTable().Insert(s.ctx, &api.ProjectEnrollment{ + ProjectKey: proj.Key, + ClassKey: cls.Key, + Status: statusFromString(status), + EnrollmentMetadata: metadata, + }) + require.NoError(s.t, err) +} + +func (s *updateProjectEnrollmentSuite) UpdatesEnrollmentForToWithStatusAndMetadata(issuer, projId, clsId, status, metadata string) { + _, s.err = s.k.UpdateProjectEnrollment(s.ctx, &v1.MsgUpdateProjectEnrollment{ + Issuer: s.addrs[issuer].String(), + ProjectId: projId, + ClassId: clsId, + NewStatus: v1.ProjectEnrollmentStatus(statusFromString(status)), + Metadata: metadata, + }) +} + +func (s *updateProjectEnrollmentSuite) ExpectNoError() { + require.NoError(s.t, s.err) +} + +func (s *updateProjectEnrollmentSuite) ExpectEnrollmentForToToBeWithMetadata(projId, clsId, status, metadata string) { + enrollment, err := s.getEnrollment(projId, clsId) + require.NoError(s.t, err) + require.Equal(s.t, statusFromString(status), enrollment.Status) + require.Equal(s.t, metadata, enrollment.EnrollmentMetadata) +} + +func (s *updateProjectEnrollmentSuite) ExpectEnrollmentExistsForToToBe(projId, clsId, exists string) { + enrollment, err := s.getEnrollment(projId, clsId) + if exists == "true" { + require.NoError(s.t, err) + } else if exists == "false" { + if !ormerrors.IsNotFound(err) { + s.t.Fatalf("expected project enrollment not found, got %v", enrollment) + } + } else { + s.t.Fatalf("invalid exists value: %s", exists) + } +} + +func (s *updateProjectEnrollmentSuite) ExpectErrorContains(a string) { + if a == "" { + require.NoError(s.t, s.err) + } else { + require.ErrorContains(s.t, s.err, a) + } +} + +func (s *updateProjectEnrollmentSuite) IfNoErrorExpectEventupdateprojectenrollmentWithProperties(a gocuke.DocString) { + if s.err != nil { + return + } + + s.ExpectEventupdateprojectenrollmentWithProperties(a) +} + +func (s *updateProjectEnrollmentSuite) ExpectEventupdateprojectenrollmentWithProperties(a gocuke.DocString) { + var evtExpected v1.EventUpdateProjectEnrollment + err := jsonpb.UnmarshalString(a.Content, &evtExpected) + require.NoError(s.t, err) + + // update issuer to actual address + evtExpected.Issuer = s.addrs[evtExpected.Issuer].String() + + evtActual, found := testutil.GetEvent(&evtExpected, s.sdkCtx.EventManager().Events()) + require.True(s.t, found) + + err = testutil.MatchEvent(&evtExpected, evtActual) + require.NoError(s.t, err) +} + +func (s *updateProjectEnrollmentSuite) getEnrollment(projId, clsId string) (*api.ProjectEnrollment, error) { + proj, err := s.stateStore.ProjectTable().GetById(s.ctx, projId) + require.NoError(s.t, err) + cls, err := s.stateStore.ClassTable().GetById(s.ctx, clsId) + require.NoError(s.t, err) + return s.stateStore.ProjectEnrollmentTable().Get(s.ctx, proj.Key, cls.Key) +} + +func statusFromString(statusName string) api.ProjectEnrollmentStatus { + var status api.ProjectEnrollmentStatus + return api.ProjectEnrollmentStatus( + status.Descriptor().Values(). + ByName(protoreflect.Name(fmt.Sprintf("PROJECT_ENROLLMENT_STATUS_%s", statusName))). + Number()) +} diff --git a/x/ecocredit/base/keeper/msg_update_project_fee.go b/x/ecocredit/base/keeper/msg_update_project_fee.go new file mode 100644 index 0000000000..89aa08306d --- /dev/null +++ b/x/ecocredit/base/keeper/msg_update_project_fee.go @@ -0,0 +1,31 @@ +package keeper + +import ( + "context" + + sdkv1beta1 "github.com/cosmos/cosmos-sdk/api/cosmos/base/v1beta1" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + regentypes "github.com/regen-network/regen-ledger/types/v2" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func (k Keeper) UpdateProjectFee(ctx context.Context, req *types.MsgUpdateProjectFee) (*types.MsgUpdateProjectFeeResponse, error) { + if k.authority.String() != req.Authority { + return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority: expected %s, got %s", k.authority, req.Authority) + } + + var classFee *sdkv1beta1.Coin + if req.Fee != nil && req.Fee.IsPositive() { + classFee = regentypes.CoinToProtoCoin(*req.Fee) + } + + if err := k.stateStore.ProjectFeeTable().Save(ctx, &api.ProjectFee{ + Fee: classFee, + }); err != nil { + return nil, err + } + + return &types.MsgUpdateProjectFeeResponse{}, nil +} diff --git a/x/ecocredit/base/keeper/msg_update_project_fee_test.go b/x/ecocredit/base/keeper/msg_update_project_fee_test.go new file mode 100644 index 0000000000..9d009b6e72 --- /dev/null +++ b/x/ecocredit/base/keeper/msg_update_project_fee_test.go @@ -0,0 +1,82 @@ +package keeper + +import ( + "testing" + + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" + + basev1beta1 "github.com/cosmos/cosmos-sdk/api/cosmos/base/v1beta1" + sdk "github.com/cosmos/cosmos-sdk/types" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + v1 "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +type updateProjectFeeSuite struct { + *baseSuite + err error + addrs map[string]sdk.AccAddress +} + +func TestUpdateProjectFee(t *testing.T) { + gocuke.NewRunner(t, &updateProjectFeeSuite{}). + Path("./features/msg_update_project_fee.feature"). + Run() +} + +func (s *updateProjectFeeSuite) Before(t gocuke.TestingT) { + s.baseSuite = setupBase(t) + s.addrs = map[string]sdk.AccAddress{ + "gov": s.k.authority, + "bob": s.addr, + } +} + +func (s *updateProjectFeeSuite) CurrentFee(amount string) { + if amount != "" { + require.NoError(s.t, s.stateStore.ProjectFeeTable().Save(s.ctx, &api.ProjectFee{ + Fee: &basev1beta1.Coin{ + Denom: "regen", + Amount: amount, + }, + })) + } +} + +func (s *updateProjectFeeSuite) UpdatesTheFeeTo(auth, fee string) { + if fee == "" { + _, s.err = s.k.UpdateProjectFee(s.ctx, &v1.MsgUpdateProjectFee{ + Authority: s.addrs[auth].String(), + }) + } else { + amount, ok := sdk.NewIntFromString(fee) + require.True(s.t, ok, "invalid fee amount") + _, s.err = s.k.UpdateProjectFee(s.ctx, &v1.MsgUpdateProjectFee{ + Authority: s.addrs[auth].String(), + Fee: &sdk.Coin{Denom: "regen", Amount: amount}, + }) + } +} + +func (s *updateProjectFeeSuite) ExpectErrorContains(a string) { + if a == "" { + require.NoError(s.t, s.err) + } else { + require.ErrorContains(s.t, s.err, a) + } +} + +func (s *updateProjectFeeSuite) ExpectProjectFeeIs(a string) { + actual, err := s.stateStore.ProjectFeeTable().Get(s.ctx) + require.NoError(s.t, err) + require.NotNil(s.t, actual) + if a == "" { + if actual.Fee == nil || actual.Fee.Amount == "" || actual.Fee.Amount == "0" { + return + } + s.t.Fatalf("expected no fee, got %s", actual.Fee.Amount) + } else { + require.Equal(s.t, a, actual.Fee.Amount) + } +} diff --git a/x/ecocredit/base/keeper/query_project_enrollment.go b/x/ecocredit/base/keeper/query_project_enrollment.go new file mode 100644 index 0000000000..36ecea7f42 --- /dev/null +++ b/x/ecocredit/base/keeper/query_project_enrollment.go @@ -0,0 +1,35 @@ +package keeper + +import ( + "context" + + regenerrors "github.com/regen-network/regen-ledger/types/v2/errors" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func (k Keeper) ProjectEnrollment(ctx context.Context, request *types.QueryProjectEnrollmentRequest) (*types.QueryProjectEnrollmentResponse, error) { + project, err := k.stateStore.ProjectTable().GetById(ctx, request.ProjectId) + if err != nil { + return nil, regenerrors.ErrNotFound.Wrapf("could not get project with id %s: %s", request.ProjectId, err.Error()) + } + + class, err := k.stateStore.ClassTable().GetById(ctx, request.ClassId) + if err != nil { + return nil, regenerrors.ErrNotFound.Wrapf("could not get class with id %s: %s", request.ClassId, err.Error()) + } + + enrollment, err := k.stateStore.ProjectEnrollmentTable().Get(ctx, project.Key, class.Key) + if err != nil { + return nil, regenerrors.ErrNotFound.Wrapf("could not get enrollment for project %s and class %s: %s", project.Id, class.Id, err.Error()) + } + + info := types.EnrollmentInfo{ + ProjectId: project.Id, + ClassId: class.Id, + Status: types.ProjectEnrollmentStatus(enrollment.Status), + ApplicationMetadata: enrollment.ApplicationMetadata, + EnrollmentMetadata: enrollment.EnrollmentMetadata, + } + + return &types.QueryProjectEnrollmentResponse{Enrollment: &info}, nil +} diff --git a/x/ecocredit/base/keeper/query_project_enrollment_test.go b/x/ecocredit/base/keeper/query_project_enrollment_test.go new file mode 100644 index 0000000000..971123a3f4 --- /dev/null +++ b/x/ecocredit/base/keeper/query_project_enrollment_test.go @@ -0,0 +1,52 @@ +package keeper + +import ( + "testing" + + "github.com/stretchr/testify/require" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func TestQuery_ProjectEnrollment(t *testing.T) { + t.Parallel() + s := setupBase(t) + + // insert project + projId := "P001" + projKey, err := s.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ + Id: projId, + }) + require.NoError(t, err) + + // insert class + clsId := "C01" + clsKey, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + Id: clsId, + }) + require.NoError(t, err) + + // insert project enrollment + appMetadata := "foobar" + enrollment := &api.ProjectEnrollment{ + ProjectKey: projKey, + ClassKey: clsKey, + Status: 0, + ApplicationMetadata: appMetadata, + EnrollmentMetadata: "", + } + require.NoError(t, s.stateStore.ProjectEnrollmentTable().Insert(s.ctx, enrollment)) + + // query project enrollment by project and class id + res, err := s.k.ProjectEnrollment(s.ctx, &types.QueryProjectEnrollmentRequest{ + ProjectId: projId, + ClassId: clsId, + }) + require.NoError(t, err) + require.Equal(t, projId, res.Enrollment.ProjectId) + require.Equal(t, clsId, res.Enrollment.ClassId) + require.Equal(t, 0, int(res.Enrollment.Status)) + require.Equal(t, appMetadata, res.Enrollment.ApplicationMetadata) + require.Equal(t, "", res.Enrollment.EnrollmentMetadata) +} diff --git a/x/ecocredit/base/keeper/query_project_enrollments.go b/x/ecocredit/base/keeper/query_project_enrollments.go new file mode 100644 index 0000000000..a0c227694f --- /dev/null +++ b/x/ecocredit/base/keeper/query_project_enrollments.go @@ -0,0 +1,106 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/orm/model/ormlist" + "github.com/cosmos/cosmos-sdk/types/query" + + ecocreditv1 "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + regenerrors "github.com/regen-network/regen-ledger/types/v2/errors" + "github.com/regen-network/regen-ledger/types/v2/ormutil" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func (k Keeper) ProjectEnrollments(ctx context.Context, request *types.QueryProjectEnrollmentsRequest) (*types.QueryProjectEnrollmentsResponse, error) { + pg, err := ormutil.GogoPageReqToPulsarPageReq(request.Pagination) + if err != nil { + return nil, regenerrors.ErrInvalidArgument.Wrap(err.Error()) + } + + var it ecocreditv1.ProjectEnrollmentIterator + if request.ClassId != "" && request.ProjectId != "" { + res, err := k.ProjectEnrollment(ctx, &types.QueryProjectEnrollmentRequest{ + ProjectId: request.ProjectId, + ClassId: request.ClassId, + }) + if err != nil { + return nil, err + } + + return &types.QueryProjectEnrollmentsResponse{ + Enrollments: []*types.EnrollmentInfo{res.Enrollment}, + Pagination: &query.PageResponse{Total: 1}, + }, nil + } else if request.ProjectId != "" { + project, err := k.stateStore.ProjectTable().GetById(ctx, request.ProjectId) + if err != nil { + return nil, regenerrors.ErrNotFound.Wrapf("could not get project with id %s: %s", request.ProjectId, err.Error()) + } + + it, err = k.stateStore.ProjectEnrollmentTable().List(ctx, + ecocreditv1.ProjectEnrollmentProjectKeyClassKeyIndexKey{}.WithProjectKey(project.Key), + ormlist.Paginate(pg)) + if err != nil { + return nil, err + } + } else if request.ClassId != "" { + cls, err := k.stateStore.ClassTable().GetById(ctx, request.ClassId) + if err != nil { + return nil, regenerrors.ErrNotFound.Wrapf("could not get class with id %s: %s", request.ClassId, err.Error()) + } + + it, err = k.stateStore.ProjectEnrollmentTable().List(ctx, + ecocreditv1.ProjectEnrollmentClassKeyIndexKey{}.WithClassKey(cls.Key), + ormlist.Paginate(pg)) + if err != nil { + return nil, err + } + } else { + it, err = k.stateStore.ProjectEnrollmentTable().List(ctx, + ecocreditv1.ProjectEnrollmentPrimaryKey{}, + ormlist.Paginate(pg)) + } + if err != nil { + return nil, err + } + defer it.Close() + + enrollments := make([]*types.EnrollmentInfo, 0) + for it.Next() { + enrollment, err := it.Value() + if err != nil { + return nil, err + } + + project, err := k.stateStore.ProjectTable().Get(ctx, enrollment.ProjectKey) + if err != nil { + return nil, regenerrors.ErrNotFound.Wrapf("could not get project with key: %d", enrollment.ProjectKey) + } + + class, err := k.stateStore.ClassTable().Get(ctx, enrollment.ClassKey) + if err != nil { + return nil, regenerrors.ErrNotFound.Wrapf("could not get class with key: %d", enrollment.ClassKey) + } + + info := &types.EnrollmentInfo{ + ProjectId: project.Id, + ClassId: class.Id, + Status: types.ProjectEnrollmentStatus(enrollment.Status), + ApplicationMetadata: enrollment.ApplicationMetadata, + EnrollmentMetadata: enrollment.EnrollmentMetadata, + } + + enrollments = append(enrollments, info) + } + + pr, err := ormutil.PulsarPageResToGogoPageRes(it.PageResponse()) + if err != nil { + return nil, regenerrors.ErrInternal.Wrap(err.Error()) + } + + return &types.QueryProjectEnrollmentsResponse{ + Enrollments: enrollments, + Pagination: pr, + }, nil +} diff --git a/x/ecocredit/base/keeper/query_project_enrollments_test.go b/x/ecocredit/base/keeper/query_project_enrollments_test.go new file mode 100644 index 0000000000..b562a6a923 --- /dev/null +++ b/x/ecocredit/base/keeper/query_project_enrollments_test.go @@ -0,0 +1,83 @@ +package keeper + +import ( + "testing" + + "github.com/stretchr/testify/require" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/base/types/v1" +) + +func TestQuery_ProjectEnrollments(t *testing.T) { + t.Parallel() + s := setupBase(t) + + // insert projects + projId1 := "P001" + projKey1, err := s.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ + Id: projId1, + }) + require.NoError(t, err) + + projId2 := "P002" + projKey2, err := s.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ + Id: projId2, + }) + require.NoError(t, err) + + // insert classes + clsId1 := "C01" + clsKey1, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + Id: clsId1, + }) + require.NoError(t, err) + + clsId2 := "BIO01" + clsKey2, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + Id: clsId2, + }) + require.NoError(t, err) + + // insert enrollments + enrollment1 := &api.ProjectEnrollment{ + ProjectKey: projKey1, + ClassKey: clsKey1, + } + + enrollment2 := &api.ProjectEnrollment{ + ProjectKey: projKey1, + ClassKey: clsKey2, + } + + enrollment3 := &api.ProjectEnrollment{ + ProjectKey: projKey2, + ClassKey: clsKey2, + } + + for _, enrollment := range []*api.ProjectEnrollment{enrollment1, enrollment2, enrollment3} { + require.NoError(t, s.stateStore.ProjectEnrollmentTable().Insert(s.ctx, enrollment)) + } + + // query project enrollments by project id + res, err := s.k.ProjectEnrollments(s.ctx, &types.QueryProjectEnrollmentsRequest{ + ProjectId: projId1, + }) + require.NoError(t, err) + require.Len(t, res.Enrollments, 2) + require.Equal(t, projId1, res.Enrollments[0].ProjectId) + require.Equal(t, clsId1, res.Enrollments[0].ClassId) + require.Equal(t, projId1, res.Enrollments[1].ProjectId) + require.Equal(t, clsId2, res.Enrollments[1].ClassId) + + // query project enrollments by class id + res, err = s.k.ProjectEnrollments(s.ctx, &types.QueryProjectEnrollmentsRequest{ + ClassId: clsId2, + }) + require.NoError(t, err) + require.Len(t, res.Enrollments, 2) + require.Equal(t, projId1, res.Enrollments[0].ProjectId) + require.Equal(t, clsId2, res.Enrollments[0].ClassId) + require.Equal(t, projId2, res.Enrollments[1].ProjectId) + require.Equal(t, clsId2, res.Enrollments[1].ClassId) +} diff --git a/x/ecocredit/base/keeper/query_project_info.go b/x/ecocredit/base/keeper/query_project_info.go index e155dae29a..3a313c5cdb 100644 --- a/x/ecocredit/base/keeper/query_project_info.go +++ b/x/ecocredit/base/keeper/query_project_info.go @@ -18,15 +18,9 @@ func (k Keeper) Project(ctx context.Context, request *types.QueryProjectRequest) admin := sdk.AccAddress(project.Admin) - class, err := k.stateStore.ClassTable().Get(ctx, project.ClassKey) - if err != nil { - return nil, regenerrors.ErrNotFound.Wrapf("could not get class with key %d: %s", project.ClassKey, err.Error()) - } - info := types.ProjectInfo{ Id: project.Id, Admin: admin.String(), - ClassId: class.Id, Jurisdiction: project.Jurisdiction, Metadata: project.Metadata, ReferenceId: project.ReferenceId, diff --git a/x/ecocredit/base/keeper/query_project_info_test.go b/x/ecocredit/base/keeper/query_project_info_test.go index d4962632fd..4a50805473 100644 --- a/x/ecocredit/base/keeper/query_project_info_test.go +++ b/x/ecocredit/base/keeper/query_project_info_test.go @@ -16,14 +16,13 @@ func TestQuery_Project(t *testing.T) { s := setupBase(t) // insert class - classKey, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + _, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ Id: "C01", }) assert.NilError(t, err) project := &api.Project{ Id: "C01-001", - ClassKey: classKey, Jurisdiction: "US-CA", Metadata: "data", ReferenceId: "R01", @@ -37,7 +36,6 @@ func TestQuery_Project(t *testing.T) { res, err := s.k.Project(s.ctx, &types.QueryProjectRequest{ProjectId: "C01-001"}) assert.NilError(t, err) assert.Equal(t, project.Id, res.Project.Id) - assert.Equal(t, "C01", res.Project.ClassId) assert.Equal(t, project.Jurisdiction, res.Project.Jurisdiction) assert.Equal(t, project.Metadata, res.Project.Metadata) assert.Equal(t, project.ReferenceId, res.Project.ReferenceId) diff --git a/x/ecocredit/base/keeper/query_projects.go b/x/ecocredit/base/keeper/query_projects.go index 455a368132..413c33a9b0 100644 --- a/x/ecocredit/base/keeper/query_projects.go +++ b/x/ecocredit/base/keeper/query_projects.go @@ -34,15 +34,9 @@ func (k Keeper) Projects(ctx context.Context, request *types.QueryProjectsReques admin := sdk.AccAddress(project.Admin) - class, err := k.stateStore.ClassTable().Get(ctx, project.ClassKey) - if err != nil { - return nil, regenerrors.ErrNotFound.Wrapf("class with key: %d", project.ClassKey) - } - info := types.ProjectInfo{ Id: project.Id, Admin: admin.String(), - ClassId: class.Id, Jurisdiction: project.Jurisdiction, Metadata: project.Metadata, ReferenceId: project.ReferenceId, diff --git a/x/ecocredit/base/keeper/query_projects_by_admin.go b/x/ecocredit/base/keeper/query_projects_by_admin.go index 7f52d61af0..e481f57bf1 100644 --- a/x/ecocredit/base/keeper/query_projects_by_admin.go +++ b/x/ecocredit/base/keeper/query_projects_by_admin.go @@ -36,15 +36,9 @@ func (k Keeper) ProjectsByAdmin(ctx context.Context, req *types.QueryProjectsByA return nil, err } - class, err := k.stateStore.ClassTable().Get(ctx, project.ClassKey) - if err != nil { - return nil, regenerrors.ErrNotFound.Wrapf("unable to get class with key: %d: %s", project.ClassKey, err.Error()) - } - projects = append(projects, &types.ProjectInfo{ Id: project.Id, Admin: req.Admin, - ClassId: class.Id, Jurisdiction: project.Jurisdiction, Metadata: project.Metadata, ReferenceId: project.ReferenceId, diff --git a/x/ecocredit/base/keeper/query_projects_by_admin_test.go b/x/ecocredit/base/keeper/query_projects_by_admin_test.go index 792987a44c..f483149394 100644 --- a/x/ecocredit/base/keeper/query_projects_by_admin_test.go +++ b/x/ecocredit/base/keeper/query_projects_by_admin_test.go @@ -21,7 +21,7 @@ func TestQuery_Projects_By_Admin(t *testing.T) { _, _, admin2 := testdata.KeyTestPubAddr() // insert class - classKey, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + _, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ Id: "C01", }) assert.NilError(t, err) @@ -29,7 +29,6 @@ func TestQuery_Projects_By_Admin(t *testing.T) { // create two projects project1 := &api.Project{ Id: "C01-001", - ClassKey: classKey, Admin: s.addr, Jurisdiction: "US-CA", Metadata: "data", @@ -40,7 +39,6 @@ func TestQuery_Projects_By_Admin(t *testing.T) { project := &api.Project{ Id: "C01-002", - ClassKey: classKey, Admin: s.addr, Jurisdiction: "US-CA", Metadata: "data", @@ -52,7 +50,6 @@ func TestQuery_Projects_By_Admin(t *testing.T) { // create project with different admin project = &api.Project{ Id: "C01-003", - ClassKey: classKey, Admin: admin2, Jurisdiction: "US-CA", Metadata: "data", @@ -75,7 +72,6 @@ func TestQuery_Projects_By_Admin(t *testing.T) { assert.NilError(t, err) assert.Equal(t, len(res.Projects), 1) assert.Equal(t, project1.Id, res.Projects[0].Id) - assert.Equal(t, "C01", res.Projects[0].ClassId) assert.Equal(t, sdk.AccAddress(project1.Admin).String(), res.Projects[0].Admin) assert.Equal(t, project1.Jurisdiction, res.Projects[0].Jurisdiction) assert.Equal(t, res.Pagination.Total, uint64(2)) diff --git a/x/ecocredit/base/keeper/query_projects_by_class.go b/x/ecocredit/base/keeper/query_projects_by_class.go index ad4d48abca..32a82b896f 100644 --- a/x/ecocredit/base/keeper/query_projects_by_class.go +++ b/x/ecocredit/base/keeper/query_projects_by_class.go @@ -3,6 +3,8 @@ package keeper import ( "context" + "google.golang.org/protobuf/proto" + "github.com/cosmos/cosmos-sdk/orm/model/ormlist" sdk "github.com/cosmos/cosmos-sdk/types" @@ -24,7 +26,12 @@ func (k Keeper) ProjectsByClass(ctx context.Context, request *types.QueryProject return nil, regenerrors.ErrNotFound.Wrapf("could not get class with id %s: %s", request.ClassId, err.Error()) } - it, err := k.stateStore.ProjectTable().List(ctx, api.ProjectClassKeyIdIndexKey{}.WithClassKey(cInfo.Key), ormlist.Paginate(pg)) + it, err := k.stateStore.ProjectEnrollmentTable().List(ctx, api.ProjectEnrollmentClassKeyIndexKey{}.WithClassKey(cInfo.Key), + ormlist.Paginate(pg), + ormlist.Filter(func(msg proto.Message) bool { + enrollment := msg.(*api.ProjectEnrollment) + return enrollment.Status == api.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED + })) if err != nil { return nil, err } @@ -32,22 +39,21 @@ func (k Keeper) ProjectsByClass(ctx context.Context, request *types.QueryProject projects := make([]*types.ProjectInfo, 0) for it.Next() { - project, err := it.Value() + enrollment, err := it.Value() if err != nil { return nil, err } - admin := sdk.AccAddress(project.Admin) - - class, err := k.stateStore.ClassTable().Get(ctx, project.ClassKey) + project, err := k.stateStore.ProjectTable().Get(ctx, enrollment.ProjectKey) if err != nil { - return nil, regenerrors.ErrNotFound.Wrapf("could not get class with key: %d", project.ClassKey) + return nil, regenerrors.ErrNotFound.Wrapf("could not get project with key: %d", enrollment.ProjectKey) } + admin := sdk.AccAddress(project.Admin) + info := types.ProjectInfo{ Id: project.Id, Admin: admin.String(), - ClassId: class.Id, Jurisdiction: project.Jurisdiction, Metadata: project.Metadata, ReferenceId: project.ReferenceId, diff --git a/x/ecocredit/base/keeper/query_projects_by_class_test.go b/x/ecocredit/base/keeper/query_projects_by_class_test.go index b074f21eec..7c2c17668b 100644 --- a/x/ecocredit/base/keeper/query_projects_by_class_test.go +++ b/x/ecocredit/base/keeper/query_projects_by_class_test.go @@ -17,24 +17,36 @@ func TestQuery_ProjectsByClass(t *testing.T) { s := setupBase(t) // insert credit class - classKey, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + clsId, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ Id: "C01", }) assert.NilError(t, err) project := &api.Project{ Id: "C01-001", - ClassKey: classKey, Jurisdiction: "US-CA", Metadata: "metadata", } // insert two projects under "C01" credit class - assert.NilError(t, s.stateStore.ProjectTable().Insert(s.ctx, project)) - assert.NilError(t, s.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ - Id: "C01-002", - ClassKey: classKey, - })) + id, err := s.stateStore.ProjectTable().InsertReturningID(s.ctx, project) + assert.NilError(t, err) + err = s.stateStore.ProjectEnrollmentTable().Insert(s.ctx, &api.ProjectEnrollment{ + ProjectKey: id, + ClassKey: clsId, + Status: api.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + assert.NilError(t, err) + id, err = s.stateStore.ProjectTable().InsertReturningID(s.ctx, &api.Project{ + Id: "C01-002", + }) + assert.NilError(t, err) + err = s.stateStore.ProjectEnrollmentTable().Insert(s.ctx, &api.ProjectEnrollment{ + ProjectKey: id, + ClassKey: clsId, + Status: api.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + assert.NilError(t, err) // query projects by "C01" credit class res, err := s.k.ProjectsByClass(s.ctx, &types.QueryProjectsByClassRequest{ @@ -49,7 +61,6 @@ func TestQuery_ProjectsByClass(t *testing.T) { // check project properties assert.Equal(t, project.Id, res.Projects[0].Id) - assert.Equal(t, "C01", res.Projects[0].ClassId) assert.Equal(t, project.Jurisdiction, res.Projects[0].Jurisdiction) assert.Equal(t, project.Metadata, res.Projects[0].Metadata) diff --git a/x/ecocredit/base/keeper/query_projects_by_reference_id.go b/x/ecocredit/base/keeper/query_projects_by_reference_id.go index 4ab8ddfd63..cff41f85e0 100644 --- a/x/ecocredit/base/keeper/query_projects_by_reference_id.go +++ b/x/ecocredit/base/keeper/query_projects_by_reference_id.go @@ -36,15 +36,9 @@ func (k Keeper) ProjectsByReferenceId(ctx context.Context, req *types.QueryProje return nil, err } - class, err := k.stateStore.ClassTable().Get(ctx, project.ClassKey) - if err != nil { - return nil, regenerrors.ErrNotFound.Wrapf("class with key: %d", project.ClassKey) - } - info := &types.ProjectInfo{ Id: project.Id, Admin: sdk.AccAddress(project.Admin).String(), - ClassId: class.Id, Jurisdiction: project.Jurisdiction, Metadata: project.Metadata, ReferenceId: project.ReferenceId, diff --git a/x/ecocredit/base/keeper/query_projects_by_reference_id_test.go b/x/ecocredit/base/keeper/query_projects_by_reference_id_test.go index 7fd1cabee2..65c61de51c 100644 --- a/x/ecocredit/base/keeper/query_projects_by_reference_id_test.go +++ b/x/ecocredit/base/keeper/query_projects_by_reference_id_test.go @@ -16,14 +16,13 @@ func TestQuery_ProjectsByReferenceId(t *testing.T) { s := setupBase(t) // insert credit class - classKey, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + _, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ Id: "C01", }) assert.NilError(t, err) project := &api.Project{ Id: "C01-001", - ClassKey: classKey, Jurisdiction: "US-CA", Metadata: "metadata", ReferenceId: "VCS-001", @@ -33,14 +32,12 @@ func TestQuery_ProjectsByReferenceId(t *testing.T) { assert.NilError(t, s.stateStore.ProjectTable().Insert(s.ctx, project)) assert.NilError(t, s.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ Id: "C01-002", - ClassKey: classKey, ReferenceId: "VCS-001", })) // insert one project without a reference id assert.NilError(t, s.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ - Id: "C01-003", - ClassKey: classKey, + Id: "C01-003", })) // query projects by "VCS-001" reference id @@ -56,7 +53,6 @@ func TestQuery_ProjectsByReferenceId(t *testing.T) { // check project properties assert.Equal(t, project.Id, res.Projects[0].Id) - assert.Equal(t, "C01", res.Projects[0].ClassId) assert.Equal(t, "VCS-001", res.Projects[0].ReferenceId) assert.Equal(t, project.Jurisdiction, res.Projects[0].Jurisdiction) diff --git a/x/ecocredit/base/keeper/query_projects_test.go b/x/ecocredit/base/keeper/query_projects_test.go index b34e64c705..6c14e80b4d 100644 --- a/x/ecocredit/base/keeper/query_projects_test.go +++ b/x/ecocredit/base/keeper/query_projects_test.go @@ -16,14 +16,13 @@ func TestQuery_Projects(t *testing.T) { s := setupBase(t) // insert credit class - classKey, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ + _, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ Id: "C01", }) assert.NilError(t, err) project := &api.Project{ Id: "C01-001", - ClassKey: classKey, Jurisdiction: "US-CA", Metadata: "metadata", } @@ -31,8 +30,7 @@ func TestQuery_Projects(t *testing.T) { // insert two projects assert.NilError(t, s.stateStore.ProjectTable().Insert(s.ctx, project)) assert.NilError(t, s.stateStore.ProjectTable().Insert(s.ctx, &api.Project{ - Id: "C01-002", - ClassKey: classKey, + Id: "C01-002", })) // query projects with pagination @@ -47,7 +45,6 @@ func TestQuery_Projects(t *testing.T) { // check project properties assert.Equal(t, project.Id, res.Projects[0].Id) - assert.Equal(t, "C01", res.Projects[0].ClassId) assert.Equal(t, project.Jurisdiction, res.Projects[0].Jurisdiction) assert.Equal(t, project.Metadata, res.Projects[0].Metadata) } diff --git a/x/ecocredit/base/simulation/msg_add_credit_type.go b/x/ecocredit/base/simulation/msg_add_credit_type.go index f8cea64189..d98f578b87 100644 --- a/x/ecocredit/base/simulation/msg_add_credit_type.go +++ b/x/ecocredit/base/simulation/msg_add_credit_type.go @@ -49,6 +49,9 @@ func SimulateMsgAddCreditType(ak ecocredit.AccountKeeper, bk ecocredit.BankKeepe abbrev := simtypes.RandStringOfLength(r, simtypes.RandIntBetween(r, 1, 3)) abbrev = strings.ToUpper(abbrev) + if abbrev == "P" { // the abbreviation "P" is reserved for projects + abbrev = "PP" + } name := simtypes.RandStringOfLength(r, simtypes.RandIntBetween(r, 1, 10)) _, err = qryClient.CreditType(sdkCtx, &types.QueryCreditTypeRequest{ diff --git a/x/ecocredit/base/simulation/msg_create_batch.go b/x/ecocredit/base/simulation/msg_create_batch.go index 2a3214acce..cc80ed8b45 100644 --- a/x/ecocredit/base/simulation/msg_create_batch.go +++ b/x/ecocredit/base/simulation/msg_create_batch.go @@ -63,6 +63,7 @@ func SimulateMsgCreateBatch(ak ecocredit.AccountKeeper, bk ecocredit.BankKeeper, msg := &types.MsgCreateBatch{ Issuer: issuer.Address.String(), ProjectId: project.Id, + ClassId: class.Id, Issuance: generateBatchIssuance(r, accs), StartDate: &now, EndDate: &tenHours, diff --git a/x/ecocredit/base/types/v1/features/msg_add_credit_type.feature b/x/ecocredit/base/types/v1/features/msg_add_credit_type.feature index 6573ca93a9..330d89af81 100644 --- a/x/ecocredit/base/types/v1/features/msg_add_credit_type.feature +++ b/x/ecocredit/base/types/v1/features/msg_add_credit_type.feature @@ -137,3 +137,20 @@ Feature: MsgAddCreditType } } """ + + + Scenario: an error is returned for the reversed abbreviation P + Given the message + """ + { + "authority": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", + "credit_type": { + "abbreviation":"P", + "name":"PPP", + "unit":"ppp", + "precision":6 + } + } + """ + When the message is validated + Then expect the error "credit type: abbreviation: P is reserved as the prefix for project IDs: parse error: invalid request" diff --git a/x/ecocredit/base/types/v1/features/msg_bridge.feature b/x/ecocredit/base/types/v1/features/msg_bridge.feature index 4e51fdd91f..0766aa0cfd 100644 --- a/x/ecocredit/base/types/v1/features/msg_bridge.feature +++ b/x/ecocredit/base/types/v1/features/msg_bridge.feature @@ -118,23 +118,6 @@ Feature: MsgBridge When the message is validated Then expect the error "credits[0]: batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if credits batch denom is not formatted - Given the message - """ - { - "owner": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", - "target": "polygon", - "recipient": "0x323b5d4c32345ced77393b3530b1eed0f346429d", - "credits": [ - { - "batch_denom": "foo" - } - ] - } - """ - When the message is validated - Then expect the error "credits[0]: batch denom: expected format ---: parse error: invalid request" - Scenario: an error is returned if credits amount is empty Given the message """ diff --git a/x/ecocredit/base/types/v1/features/msg_create_batch.feature b/x/ecocredit/base/types/v1/features/msg_create_batch.feature index ebd2e5c07b..d83f2c2f82 100644 --- a/x/ecocredit/base/types/v1/features/msg_create_batch.feature +++ b/x/ecocredit/base/types/v1/features/msg_create_batch.feature @@ -6,6 +6,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -29,6 +30,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -51,6 +53,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -77,6 +80,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -101,6 +105,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -150,7 +155,7 @@ Feature: MsgCreateBatch When the message is validated Then expect the error "project id: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if project id is not formatted + Scenario: an error is returned if class id is empty Given the message """ { @@ -159,13 +164,14 @@ Feature: MsgCreateBatch } """ When the message is validated - Then expect the error "project id: expected format -: parse error: invalid request" + Then expect the error "class id: empty string is not allowed: parse error: invalid request" Scenario: an error is returned if issuance is empty Given the message """ { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", + "class_id": "C01", "project_id": "C01-001", "issuance": [] } @@ -179,6 +185,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ {} ] @@ -195,6 +202,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -215,6 +223,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -236,6 +245,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -257,6 +267,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -279,6 +290,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -302,6 +314,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -326,6 +339,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -354,6 +368,7 @@ Feature: MsgCreateBatch { "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", "project_id": "C01-001", + "class_id": "C01", "issuance": [ { "recipient": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", @@ -374,6 +389,7 @@ Feature: MsgCreateBatch { "type":"regen/MsgCreateBatch", "value":{ + "class_id": "C01", "end_date":"2021-01-01T00:00:00Z", "issuance":[ { diff --git a/x/ecocredit/base/types/v1/features/msg_create_or_update_application.feature b/x/ecocredit/base/types/v1/features/msg_create_or_update_application.feature new file mode 100644 index 0000000000..f2f1654150 --- /dev/null +++ b/x/ecocredit/base/types/v1/features/msg_create_or_update_application.feature @@ -0,0 +1,61 @@ +Feature: MsgCreateOrUpdateApplication + + Rule: project_admin is address and signer + Scenario Outline: validate admin + Given project admin "" + * project ID "P1" + * class ID "C01" + When the message is validated + Then expect error contains "" + + Examples: + | admin | error | + | | project admin | + | 0x0 | project admin | + | regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6 | | + + Scenario: project admin is signer + Given project admin "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + Then expect GetSigners returns "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + + Rule: project_id should be non-empty + Scenario Outline: validate project ID + Given project admin "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + * project ID "" + * class ID "C01" + When the message is validated + Then expect error contains "" + + Examples: + | project_id | error | + | | project id | + | P1 | | + + Rule: class_id should be non-empty + Scenario Outline: validate class ID + Given project admin "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + * project ID "P1" + * class ID "" + When the message is validated + Then expect error contains "" + + Examples: + | class_id | error | + | | class id | + | C01 | | + + Rule: metadata is optional and at most 256 characters + Scenario Outline: validate metadata + Given project admin "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + * project ID "P1" + * class ID "C01" + * metadata "" + When the message is validated + Then expect error contains "" + + Examples: + | metadata | error | + | | | + | a | | + | This is a string with 256 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac facilisis arcu. Nullam nec dui ac nunc dapibus cursus. Sed sit amet massa rutrum, auctor sapien ut, euismod dolor. Nullam vehicula tellus laoreet tincidun | | + | This is a string with 257 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac facilisis arcu. Nullam nec dui ac nunc dapibus cursus. Sed sit amet massa rutrum, auctor sapien ut, euismod dolor. Nullam vehicula tellus laoreet tincidunt | metadata | diff --git a/x/ecocredit/base/types/v1/features/msg_create_unregistered_project.feature b/x/ecocredit/base/types/v1/features/msg_create_unregistered_project.feature new file mode 100644 index 0000000000..7de3233252 --- /dev/null +++ b/x/ecocredit/base/types/v1/features/msg_create_unregistered_project.feature @@ -0,0 +1,49 @@ +Feature: MsgCreateUnregisteredProject + + Rule: admin must be signer address + Scenario Outline: validate admin + Given admin "" + And jurisdiction "US" + When the message is validated + Then expect error contains "" + + Examples: + | admin | error | + | | admin | + | 0x0 | admin | + | regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6 | | + + Scenario: admin is signer + Given admin "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + Then expect GetSigners returns "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + + Rule: jurisdiction is required and must be valid + Scenario Outline: validate jurisdiction + Given admin "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + And jurisdiction "" + When the message is validated + Then expect error contains "" + + Examples: + | jurisdiction | error | + | | jurisdiction | + | US | | + | US123 | jurisdiction | + | US-NY | | + | US-NY123 | jurisdiction | + | US-NY 123 | | + + Rule: metadata is optional and must be at most 256 characters + Scenario Outline: validate metadata + Given admin "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + And jurisdiction "US" + And metadata "" + When the message is validated + Then expect error contains "" + + Examples: + | metadata | error | + | | | + | a | | + | This is a string with 256 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac facilisis arcu. Nullam nec dui ac nunc dapibus cursus. Sed sit amet massa rutrum, auctor sapien ut, euismod dolor. Nullam vehicula tellus laoreet tincidun | | + | This is a string with 256 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac facilisis arcu. Nullam nec dui ac nunc dapibus cursus. Sed sit amet massa rutrum, auctor sapien ut, euismod dolor. Nullam vehicula tellus laoreet tincidunt | metadata | diff --git a/x/ecocredit/base/types/v1/features/msg_mint_batch_credits.feature b/x/ecocredit/base/types/v1/features/msg_mint_batch_credits.feature index 17f23c5886..445dad9cbe 100644 --- a/x/ecocredit/base/types/v1/features/msg_mint_batch_credits.feature +++ b/x/ecocredit/base/types/v1/features/msg_mint_batch_credits.feature @@ -77,17 +77,6 @@ Feature: MsgMintBatchCredits When the message is validated Then expect the error "batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if batch denom is not formatted - Given the message - """ - { - "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", - "batch_denom": "foo" - } - """ - When the message is validated - Then expect the error "batch denom: expected format ---: parse error: invalid request" - Scenario: an error is returned if issuance is empty Given the message """ diff --git a/x/ecocredit/base/types/v1/features/msg_seal_batch.feature b/x/ecocredit/base/types/v1/features/msg_seal_batch.feature index 07b49087a6..201a67f743 100644 --- a/x/ecocredit/base/types/v1/features/msg_seal_batch.feature +++ b/x/ecocredit/base/types/v1/features/msg_seal_batch.feature @@ -39,17 +39,6 @@ Feature: MsgSealBatch When the message is validated Then expect the error "batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if batch denom is not formatted - Given the message - """ - { - "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", - "batch_denom": "foo" - } - """ - When the message is validated - Then expect the error "batch denom: expected format ---: parse error: invalid request" - Scenario: a valid amino message Given the message """ diff --git a/x/ecocredit/base/types/v1/features/msg_send.feature b/x/ecocredit/base/types/v1/features/msg_send.feature index 63bf82608b..86b4dcf9fc 100644 --- a/x/ecocredit/base/types/v1/features/msg_send.feature +++ b/x/ecocredit/base/types/v1/features/msg_send.feature @@ -126,22 +126,6 @@ Feature: MsgSend When the message is validated Then expect the error "credits[0]: batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if credits batch denom is not formatted - Given the message - """ - { - "sender": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", - "recipient": "regen1tnh2q55v8wyygtt9srz5safamzdengsnlm0yy4", - "credits": [ - { - "batch_denom": "foo" - } - ] - } - """ - When the message is validated - Then expect the error "credits[0]: batch denom: expected format ---: parse error: invalid request" - Scenario: an error is returned if credits tradable amount and retired amount are empty Given the message """ diff --git a/x/ecocredit/base/types/v1/features/msg_update_batch_metadata.feature b/x/ecocredit/base/types/v1/features/msg_update_batch_metadata.feature index 26bf625df1..d7b69e3f5c 100644 --- a/x/ecocredit/base/types/v1/features/msg_update_batch_metadata.feature +++ b/x/ecocredit/base/types/v1/features/msg_update_batch_metadata.feature @@ -40,17 +40,6 @@ Feature: MsgUpdateBatchMetadata When the message is validated Then expect the error "batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if batch denom is not formatted - Given the message - """ - { - "issuer": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", - "batch_denom": "foo" - } - """ - When the message is validated - Then expect the error "batch denom: expected format ---: parse error: invalid request" - Scenario: an error is returned if new metadata is empty Given the message """ diff --git a/x/ecocredit/base/types/v1/features/msg_update_project_admin.feature b/x/ecocredit/base/types/v1/features/msg_update_project_admin.feature index edcb2f4931..eb402290d2 100644 --- a/x/ecocredit/base/types/v1/features/msg_update_project_admin.feature +++ b/x/ecocredit/base/types/v1/features/msg_update_project_admin.feature @@ -40,17 +40,6 @@ Feature: MsgUpdateProjectAdmin When the message is validated Then expect the error "project id: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if project id is not formatted - Given the message - """ - { - "admin": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", - "project_id": "foo" - } - """ - When the message is validated - Then expect the error "project id: expected format -: parse error: invalid request" - Scenario: an error is returned if new admin is empty Given the message """ diff --git a/x/ecocredit/base/types/v1/features/msg_update_project_enrollment.feature b/x/ecocredit/base/types/v1/features/msg_update_project_enrollment.feature new file mode 100644 index 0000000000..ae1dabfcac --- /dev/null +++ b/x/ecocredit/base/types/v1/features/msg_update_project_enrollment.feature @@ -0,0 +1,70 @@ +Feature: MsgUpdateProjectEnrollment + + Rule: issuer is address and signer + Scenario Outline: validate issuer + Given issuer "" + * project ID "P001" + * class ID "C01" + * new status "ACCEPTED" + When the message is validated + Then expect error contains "" + + Examples: + | issuer | error | + | | issuer: empty | + | 0x0 | invalid bech32 | + | regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6 | | + + Scenario: issuer is signer + Given issuer "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + Then expect GetSigners returns "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + + Rule: project_id and class_id must be non-empty + Scenario Outline: validate project and class IDs + Given issuer "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + * project ID "" + * class ID "" + * new status "ACCEPTED" + When the message is validated + Then expect error contains "" + + Examples: + | project_id | class_id | error | + | | C01 | project id: empty | + | P001 | C01 | | + | P001 | | class id: empty | + + Rule: new_status is specified and valid + Scenario Outline: validate status + Given issuer "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + * project ID "P001" + * class ID "C01" + * new status "" + When the message is validated + Then expect error contains "" + + Examples: + | status | error | + | UNSPECIFIED | new status: invalid | + | ACCEPTED | | + | REJECTED | | + | CHANGES_REQUESTED | | + | TERMINATED | | + | 6 | new status: invalid | + + Rule: metadata is optional and at most 256 characters + Scenario Outline: validate metadata + Given issuer "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + * project ID "P001" + * class ID "C01" + * new status "ACCEPTED" + * metadata "" + When the message is validated + Then expect error contains "" + + Examples: + | metadata | error | + | | | + | a | | + | This is a string with 256 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac facilisis arcu. Nullam nec dui ac nunc dapibus cursus. Sed sit amet massa rutrum, auctor sapien ut, euismod dolor. Nullam vehicula tellus laoreet tincidun | | + | This is a string with 257 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac facilisis arcu. Nullam nec dui ac nunc dapibus cursus. Sed sit amet massa rutrum, auctor sapien ut, euismod dolor. Nullam vehicula tellus laoreet tincidunt | metadata | diff --git a/x/ecocredit/base/types/v1/features/msg_update_project_fee.feature b/x/ecocredit/base/types/v1/features/msg_update_project_fee.feature new file mode 100644 index 0000000000..ecacb1bbc5 --- /dev/null +++ b/x/ecocredit/base/types/v1/features/msg_update_project_fee.feature @@ -0,0 +1,32 @@ +Feature: MsgUpdateProjectFee + + Rule: authority is address and signer + Scenario Outline: validate admin + Given authority "" + And fee "100regen" + When the message is validated + Then expect error contains "" + + Examples: + | auth | error | + | | invalid authority | + | 0x0 | invalid authority | + | regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6 | | + + Scenario: authority is signer + Given authority "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + Then expect GetSigners returns "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + + Rule: fee is a valid coin or nil + Scenario: valid coin + Given authority "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + And fee "100regen" + When the message is validated + Then expect no error + + Scenario: fee is nil + Given authority "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6" + And nil fee + When the message is validated + Then expect no error + diff --git a/x/ecocredit/base/types/v1/features/msg_update_project_metadata.feature b/x/ecocredit/base/types/v1/features/msg_update_project_metadata.feature index 4691c11bbb..cbaeb55668 100644 --- a/x/ecocredit/base/types/v1/features/msg_update_project_metadata.feature +++ b/x/ecocredit/base/types/v1/features/msg_update_project_metadata.feature @@ -51,17 +51,6 @@ Feature: MsgUpdateProjectMetadata When the message is validated Then expect the error "project id: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if project id is not formatted - Given the message - """ - { - "admin": "regen1depk54cuajgkzea6zpgkq36tnjwdzv4ak663u6", - "project_id": "foo" - } - """ - When the message is validated - Then expect the error "project id: expected format -: parse error: invalid request" - Scenario: an error is returned if new metadata exceeds 256 characters Given the message """ diff --git a/x/ecocredit/base/types/v1/features/state_batch.feature b/x/ecocredit/base/types/v1/features/state_batch.feature index e195a47f94..1bb1aa6885 100644 --- a/x/ecocredit/base/types/v1/features/state_batch.feature +++ b/x/ecocredit/base/types/v1/features/state_batch.feature @@ -76,19 +76,6 @@ Feature: Batch When the batch is validated Then expect the error "denom: empty string is not allowed: parse error" - Scenario: an error is returned if denom is not formatted - Given the batch - """ - { - "key": 1, - "issuer": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", - "project_key": 1, - "denom": "foo" - } - """ - When the batch is validated - Then expect the error "denom: expected format ---: parse error" - Scenario: an error is returned if metadata exceeds 256 characters Given the batch """ diff --git a/x/ecocredit/base/types/v1/features/state_project.feature b/x/ecocredit/base/types/v1/features/state_project.feature index c88cc22f8e..e8f0f2a7bd 100644 --- a/x/ecocredit/base/types/v1/features/state_project.feature +++ b/x/ecocredit/base/types/v1/features/state_project.feature @@ -7,7 +7,6 @@ Feature: Project "key": 1, "id": "C01-001", "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", - "class_key": 1, "jurisdiction": "US-WA", "metadata": "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf" } @@ -22,7 +21,6 @@ Feature: Project "key": 1, "id": "C01-001", "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", - "class_key": 1, "jurisdiction": "US-WA" } """ @@ -36,7 +34,6 @@ Feature: Project "key": 1, "id": "C01-001", "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", - "class_key": 1, "jurisdiction": "US-WA", "metadata": "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf", "reference_id": "VCS-001" @@ -63,39 +60,44 @@ Feature: Project When the project is validated Then expect the error "project id: empty string is not allowed: parse error" - Scenario: an error is returned if id is not formatted + Scenario: an error is returned if admin is empty Given the project """ { "key": 1, - "id": "foo" + "id": "C01-001" } """ When the project is validated - Then expect the error "project id: expected format -: parse error" + Then expect the error "admin: empty address string is not allowed: parse error" - Scenario: an error is returned if admin is empty + Scenario: an error is returned if class key is not empty and reference id is empty Given the project """ { "key": 1, - "id": "C01-001" + "id": "C01-001", + "class_key": 1, + "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=" } """ When the project is validated - Then expect the error "admin: empty address string is not allowed: parse error" + Then expect the error "class key must be zero unless reference id is set: parse error" - Scenario: an error is returned if class key is empty + Scenario: class key can be non-empty if reference id is set Given the project """ { "key": 1, "id": "C01-001", - "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=" + "class_key": 1, + "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", + "reference_id": "VCS-001", + "jurisdiction": "US-WA" } """ When the project is validated - Then expect the error "class key cannot be zero: parse error" + Then expect no error Scenario: an error is returned if jurisdiction is empty Given the project @@ -103,8 +105,7 @@ Feature: Project { "key": 1, "id": "C01-001", - "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", - "class_key": 1 + "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=" } """ When the project is validated @@ -117,7 +118,6 @@ Feature: Project "key": 1, "id": "C01-001", "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", - "class_key": 1, "jurisdiction": "foo" } """ @@ -131,7 +131,6 @@ Feature: Project "key": 1, "id": "C01-001", "admin": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", - "class_key": 1, "jurisdiction": "US-WA" } """ diff --git a/x/ecocredit/base/types/v1/features/types_credits.feature b/x/ecocredit/base/types/v1/features/types_credits.feature index 15b09f30e7..252f6b9703 100644 --- a/x/ecocredit/base/types/v1/features/types_credits.feature +++ b/x/ecocredit/base/types/v1/features/types_credits.feature @@ -19,16 +19,6 @@ Feature: Credits When the message is validated Then expect the error "batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if batch denom is not formatted - Given the message - """ - { - "batch_denom": "foo" - } - """ - When the message is validated - Then expect the error "batch denom: expected format ---: parse error: invalid request" - Scenario: an error is returned if amount is empty Given the message """ diff --git a/x/ecocredit/base/types/v1/msg_burn_regen.go b/x/ecocredit/base/types/v1/msg_burn_regen.go index bfe455478d..68f0a6b920 100644 --- a/x/ecocredit/base/types/v1/msg_burn_regen.go +++ b/x/ecocredit/base/types/v1/msg_burn_regen.go @@ -2,6 +2,7 @@ package v1 import ( "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" diff --git a/x/ecocredit/base/types/v1/msg_create_batch.go b/x/ecocredit/base/types/v1/msg_create_batch.go index 2516cce765..d75ce13664 100644 --- a/x/ecocredit/base/types/v1/msg_create_batch.go +++ b/x/ecocredit/base/types/v1/msg_create_batch.go @@ -34,6 +34,10 @@ func (m *MsgCreateBatch) ValidateBasic() error { return sdkerrors.ErrInvalidRequest.Wrapf("project id: %s", err) } + if err := base.ValidateClassID(m.ClassId); err != nil { + return sdkerrors.ErrInvalidRequest.Wrapf("class id: %s", err) + } + if len(m.Issuance) == 0 { return sdkerrors.ErrInvalidRequest.Wrap("issuance cannot be empty") } diff --git a/x/ecocredit/base/types/v1/msg_create_or_update_application.go b/x/ecocredit/base/types/v1/msg_create_or_update_application.go index 4157e5843e..d9ea28cd0e 100644 --- a/x/ecocredit/base/types/v1/msg_create_or_update_application.go +++ b/x/ecocredit/base/types/v1/msg_create_or_update_application.go @@ -2,7 +2,11 @@ package v1 import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + + "github.com/regen-network/regen-ledger/x/ecocredit/v3" + "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" ) var _ legacytx.LegacyMsg = &MsgCreateOrUpdateApplication{} @@ -20,7 +24,23 @@ func (m *MsgCreateOrUpdateApplication) GetSignBytes() []byte { // ValidateBasic does a sanity check on the provided data. func (m *MsgCreateOrUpdateApplication) ValidateBasic() error { - panic("implement me") + if _, err := sdk.AccAddressFromBech32(m.ProjectAdmin); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("project admin: %s", err) + } + + if err := base.ValidateProjectID(m.ProjectId); err != nil { + return sdkerrors.ErrInvalidRequest.Wrapf("project id: %s", err) + } + + if err := base.ValidateClassID(m.ClassId); err != nil { + return sdkerrors.ErrInvalidRequest.Wrapf("class id: %s", err) + } + + if len(m.Metadata) > base.MaxMetadataLength { + return ecocredit.ErrMaxLimit.Wrapf("metadata: max length %d", base.MaxMetadataLength) + } + + return nil } // GetSigners returns the expected signers for MsgCreateOrUpdateApplication. diff --git a/x/ecocredit/base/types/v1/msg_create_or_update_application_test.go b/x/ecocredit/base/types/v1/msg_create_or_update_application_test.go new file mode 100644 index 0000000000..955fee6cff --- /dev/null +++ b/x/ecocredit/base/types/v1/msg_create_or_update_application_test.go @@ -0,0 +1,56 @@ +package v1 + +import ( + "testing" + + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" +) + +type msgCreateOrUpdateApplication struct { + gocuke.TestingT + msg *MsgCreateOrUpdateApplication + err error +} + +func TestMsgCreateOrUpdateApplication(t *testing.T) { + gocuke.NewRunner(t, &msgCreateOrUpdateApplication{}).Path("./features/msg_create_or_update_application.feature").Run() +} + +func (s *msgCreateOrUpdateApplication) Before() { + s.msg = &MsgCreateOrUpdateApplication{} +} + +func (s *msgCreateOrUpdateApplication) ProjectAdmin(a string) { + s.msg.ProjectAdmin = a +} + +func (s *msgCreateOrUpdateApplication) ProjectId(a string) { + s.msg.ProjectId = a +} + +func (s *msgCreateOrUpdateApplication) ClassId(a string) { + s.msg.ClassId = a +} + +func (s *msgCreateOrUpdateApplication) Metadata(a string) { + s.msg.Metadata = a +} + +func (s *msgCreateOrUpdateApplication) TheMessageIsValidated() { + s.err = s.msg.ValidateBasic() +} + +func (s *msgCreateOrUpdateApplication) ExpectErrorContains(a string) { + if a != "" { + require.ErrorContains(s, s.err, a) + } else { + require.NoError(s, s.err) + } +} + +func (s *msgCreateOrUpdateApplication) ExpectGetsignersReturns(a string) { + signers := s.msg.GetSigners() + require.Len(s, signers, 1) + require.Equal(s, a, s.msg.GetSigners()[0].String()) +} diff --git a/x/ecocredit/base/types/v1/msg_create_unregistered_project.go b/x/ecocredit/base/types/v1/msg_create_unregistered_project.go index 4f19f58642..b7c9704ad8 100644 --- a/x/ecocredit/base/types/v1/msg_create_unregistered_project.go +++ b/x/ecocredit/base/types/v1/msg_create_unregistered_project.go @@ -2,7 +2,11 @@ package v1 import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + + "github.com/regen-network/regen-ledger/x/ecocredit/v3" + "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" ) var _ legacytx.LegacyMsg = &MsgCreateUnregisteredProject{} @@ -20,7 +24,19 @@ func (m *MsgCreateUnregisteredProject) GetSignBytes() []byte { // ValidateBasic does a sanity check on the provided data. func (m *MsgCreateUnregisteredProject) ValidateBasic() error { - panic("implement me") + if _, err := sdk.AccAddressFromBech32(m.Admin); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("admin: %s", err) + } + + if err := base.ValidateJurisdiction(m.Jurisdiction); err != nil { + return sdkerrors.ErrInvalidRequest.Wrapf("jurisdiction: %s", err) + } + + if len(m.Metadata) > base.MaxMetadataLength { + return ecocredit.ErrMaxLimit.Wrapf("metadata: max length %d", base.MaxMetadataLength) + } + + return nil } // GetSigners returns the expected signers for MsgCreateUnregisteredProject. diff --git a/x/ecocredit/base/types/v1/msg_create_unregistered_project_test.go b/x/ecocredit/base/types/v1/msg_create_unregistered_project_test.go new file mode 100644 index 0000000000..3fbd1c9ba9 --- /dev/null +++ b/x/ecocredit/base/types/v1/msg_create_unregistered_project_test.go @@ -0,0 +1,52 @@ +package v1 + +import ( + "testing" + + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" +) + +type msgCreateUnregisteredProject struct { + gocuke.TestingT + msg *MsgCreateUnregisteredProject + err error +} + +func TestMsgCreateUnregisteredProject(t *testing.T) { + gocuke.NewRunner(t, &msgCreateUnregisteredProject{}).Path("./features/msg_create_unregistered_project.feature").Run() +} + +func (s *msgCreateUnregisteredProject) Before() { + s.msg = &MsgCreateUnregisteredProject{} +} + +func (s *msgCreateUnregisteredProject) Admin(a string) { + s.msg.Admin = a +} + +func (s *msgCreateUnregisteredProject) Jurisdiction(a string) { + s.msg.Jurisdiction = a +} + +func (s *msgCreateUnregisteredProject) Metadata(a string) { + s.msg.Metadata = a +} + +func (s *msgCreateUnregisteredProject) TheMessageIsValidated() { + s.err = s.msg.ValidateBasic() +} + +func (s *msgCreateUnregisteredProject) ExpectErrorContains(a string) { + if a != "" { + require.ErrorContains(s, s.err, a) + } else { + require.NoError(s, s.err) + } +} + +func (s *msgCreateUnregisteredProject) ExpectGetsignersReturns(a string) { + signers := s.msg.GetSigners() + require.Len(s, signers, 1) + require.Equal(s, a, s.msg.GetSigners()[0].String()) +} diff --git a/x/ecocredit/base/types/v1/msg_update_project_enrollment.go b/x/ecocredit/base/types/v1/msg_update_project_enrollment.go index 14fcc692dd..1356b2fe5e 100644 --- a/x/ecocredit/base/types/v1/msg_update_project_enrollment.go +++ b/x/ecocredit/base/types/v1/msg_update_project_enrollment.go @@ -2,7 +2,11 @@ package v1 import ( sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + + "github.com/regen-network/regen-ledger/x/ecocredit/v3" + "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" ) var _ legacytx.LegacyMsg = &MsgUpdateProjectEnrollment{} @@ -20,7 +24,32 @@ func (m *MsgUpdateProjectEnrollment) GetSignBytes() []byte { // ValidateBasic does a sanity check on the provided data. func (m *MsgUpdateProjectEnrollment) ValidateBasic() error { - panic("implement me") + + if _, err := sdk.AccAddressFromBech32(m.Issuer); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("issuer: %s", err) + } + + if err := base.ValidateProjectID(m.ProjectId); err != nil { + return sdkerrors.ErrInvalidRequest.Wrapf("project id: %s", err) + } + + if err := base.ValidateClassID(m.ClassId); err != nil { + return sdkerrors.ErrInvalidRequest.Wrapf("class id: %s", err) + } + + if m.NewStatus == ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_UNSPECIFIED { + return sdkerrors.ErrInvalidRequest.Wrapf("new status: invalid") + } + + if _, ok := ProjectEnrollmentStatus_name[int32(m.NewStatus)]; !ok { + return sdkerrors.ErrInvalidRequest.Wrapf("new status: invalid") + } + + if len(m.Metadata) > base.MaxMetadataLength { + return ecocredit.ErrMaxLimit.Wrapf("metadata: max length %d", base.MaxMetadataLength) + } + + return nil } // GetSigners returns the expected signers for MsgUpdateProjectEnrollment. diff --git a/x/ecocredit/base/types/v1/msg_update_project_enrollment_test.go b/x/ecocredit/base/types/v1/msg_update_project_enrollment_test.go new file mode 100644 index 0000000000..5efe969176 --- /dev/null +++ b/x/ecocredit/base/types/v1/msg_update_project_enrollment_test.go @@ -0,0 +1,73 @@ +package v1 + +import ( + "fmt" + "strconv" + "testing" + + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/reflect/protoreflect" + + api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" +) + +type msgUpdateProjectEnrollment struct { + gocuke.TestingT + msg *MsgUpdateProjectEnrollment + err error +} + +func TestMsgUpdateProjectEnrollment(t *testing.T) { + gocuke.NewRunner(t, &msgUpdateProjectEnrollment{}).Path("./features/msg_update_project_enrollment.feature").Run() +} + +func (s *msgUpdateProjectEnrollment) Before() { + s.msg = &MsgUpdateProjectEnrollment{} +} + +func (s *msgUpdateProjectEnrollment) Issuer(a string) { + s.msg.Issuer = a +} + +func (s *msgUpdateProjectEnrollment) ProjectId(a string) { + s.msg.ProjectId = a +} + +func (s *msgUpdateProjectEnrollment) ClassId(a string) { + s.msg.ClassId = a +} + +func (s *msgUpdateProjectEnrollment) NewStatus(a string) { + n, err := strconv.Atoi(a) + if err == nil { + s.msg.NewStatus = ProjectEnrollmentStatus(n) + } else { + var status api.ProjectEnrollmentStatus + value := status.Descriptor().Values().ByName(protoreflect.Name(fmt.Sprintf("PROJECT_ENROLLMENT_STATUS_%s", a))) + if value == nil { + s.Fatalf("invalid status: %s", a) + } + s.msg.NewStatus = ProjectEnrollmentStatus(value.Number()) + } +} + +func (s *msgUpdateProjectEnrollment) Metadata(a string) { + s.msg.Metadata = a +} + +func (s *msgUpdateProjectEnrollment) TheMessageIsValidated() { + s.err = s.msg.ValidateBasic() +} + +func (s *msgUpdateProjectEnrollment) ExpectErrorContains(a string) { + if a == "" { + require.NoError(s, s.err) + } else { + require.ErrorContains(s, s.err, a) + } +} + +func (s *msgUpdateProjectEnrollment) ExpectGetsignersReturns(a string) { + require.Equal(s, a, s.msg.GetSigners()[0].String()) +} diff --git a/x/ecocredit/base/types/v1/msg_update_project_fee_test.go b/x/ecocredit/base/types/v1/msg_update_project_fee_test.go new file mode 100644 index 0000000000..0320e3475d --- /dev/null +++ b/x/ecocredit/base/types/v1/msg_update_project_fee_test.go @@ -0,0 +1,58 @@ +package v1 + +import ( + "testing" + + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type msgUpdateProjectFee struct { + gocuke.TestingT + msg *MsgUpdateProjectFee + err error +} + +func TestMsgUpdateProjectFee(t *testing.T) { + gocuke.NewRunner(t, &msgUpdateProjectFee{}).Path("./features/msg_update_project_fee.feature").Run() +} + +func (s *msgUpdateProjectFee) Before() { + s.msg = &MsgUpdateProjectFee{} +} + +func (s *msgUpdateProjectFee) Authority(a string) { + s.msg.Authority = a +} + +func (s *msgUpdateProjectFee) Fee(a string) { + coin, err := sdk.ParseCoinNormalized(a) + require.NoError(s, err) + s.msg.Fee = &coin +} + +func (s *msgUpdateProjectFee) TheMessageIsValidated() { + s.err = s.msg.ValidateBasic() +} + +func (s *msgUpdateProjectFee) ExpectErrorContains(a string) { + if a == "" { + require.NoError(s, s.err) + } else { + require.ErrorContains(s, s.err, a) + } +} + +func (s *msgUpdateProjectFee) ExpectNoError() { + require.NoError(s, s.err) +} + +func (s *msgUpdateProjectFee) ExpectGetsignersReturns(a string) { + require.Equal(s, a, s.msg.GetSigners()[0].String()) +} + +func (s *msgUpdateProjectFee) NilFee() { + s.msg.Fee = nil +} diff --git a/x/ecocredit/base/types/v1/query.pb.go b/x/ecocredit/base/types/v1/query.pb.go index 40fb3c2ef7..c09e8611ce 100644 --- a/x/ecocredit/base/types/v1/query.pb.go +++ b/x/ecocredit/base/types/v1/query.pb.go @@ -2376,9 +2376,8 @@ type ProjectInfo struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // admin is the admin of the project. Admin string `protobuf:"bytes,2,opt,name=admin,proto3" json:"admin,omitempty"` - // class_id is the unique identifier of the credit class within which the - // project was created. - ClassId string `protobuf:"bytes,3,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` + // Deprecated: use ProjectEnrollment instead. + ClassId string `protobuf:"bytes,3,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` // Deprecated: Do not use. // jurisdiction is the jurisdiction of the project. Full documentation can be // found in MsgCreateProject.jurisdiction. Jurisdiction string `protobuf:"bytes,4,opt,name=jurisdiction,proto3" json:"jurisdiction,omitempty"` @@ -2435,6 +2434,7 @@ func (m *ProjectInfo) GetAdmin() string { return "" } +// Deprecated: Do not use. func (m *ProjectInfo) GetClassId() string { if m != nil { return m.ClassId @@ -3100,7 +3100,7 @@ func (m *QueryProjectEnrollmentRequest) GetClassId() string { // Since Revision 3 type QueryProjectEnrollmentResponse struct { // project_class is the fetched project class relationship. - ProjectClass *ProjectEnrollment `protobuf:"bytes,1,opt,name=project_class,json=projectClass,proto3" json:"project_class,omitempty"` + Enrollment *EnrollmentInfo `protobuf:"bytes,1,opt,name=enrollment,proto3" json:"enrollment,omitempty"` } func (m *QueryProjectEnrollmentResponse) Reset() { *m = QueryProjectEnrollmentResponse{} } @@ -3136,9 +3136,9 @@ func (m *QueryProjectEnrollmentResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryProjectEnrollmentResponse proto.InternalMessageInfo -func (m *QueryProjectEnrollmentResponse) GetProjectClass() *ProjectEnrollment { +func (m *QueryProjectEnrollmentResponse) GetEnrollment() *EnrollmentInfo { if m != nil { - return m.ProjectClass + return m.Enrollment } return nil } @@ -3147,8 +3147,12 @@ func (m *QueryProjectEnrollmentResponse) GetProjectClass() *ProjectEnrollment { // // Since Revision 3 type QueryProjectEnrollmentsRequest struct { - // project_id is the unique identifier of the project to query. + // project_id is the unique identifier of the project to filter enrollments + // by. If not set, enrollments for all projects will be returned. ProjectId string `protobuf:"bytes,1,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + // class_id is the unique identifier of the credit class to filter enrollments + // by. If not set, enrollments for all credit classes will be returned. + ClassId string `protobuf:"bytes,3,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` // pagination defines an optional pagination for the request. Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -3193,6 +3197,13 @@ func (m *QueryProjectEnrollmentsRequest) GetProjectId() string { return "" } +func (m *QueryProjectEnrollmentsRequest) GetClassId() string { + if m != nil { + return m.ClassId + } + return "" +} + func (m *QueryProjectEnrollmentsRequest) GetPagination() *query.PageRequest { if m != nil { return m.Pagination @@ -3205,7 +3216,7 @@ func (m *QueryProjectEnrollmentsRequest) GetPagination() *query.PageRequest { // Since Revision 3 type QueryProjectEnrollmentsResponse struct { // enrollments are the fetched project credit class enrollments. - Enrollments []*ProjectEnrollment `protobuf:"bytes,1,rep,name=enrollments,proto3" json:"enrollments,omitempty"` + Enrollments []*EnrollmentInfo `protobuf:"bytes,1,rep,name=enrollments,proto3" json:"enrollments,omitempty"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -3243,7 +3254,7 @@ func (m *QueryProjectEnrollmentsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryProjectEnrollmentsResponse proto.InternalMessageInfo -func (m *QueryProjectEnrollmentsResponse) GetEnrollments() []*ProjectEnrollment { +func (m *QueryProjectEnrollmentsResponse) GetEnrollments() []*EnrollmentInfo { if m != nil { return m.Enrollments } @@ -3257,6 +3268,90 @@ func (m *QueryProjectEnrollmentsResponse) GetPagination() *query.PageResponse { return nil } +// EnrollmentInfo is the human-readable project enrollment information. +type EnrollmentInfo struct { + // project_id is the unique identifier of the project to query. + ProjectId string `protobuf:"bytes,1,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + // class_id is the unique identifier of the credit class to query. + ClassId string `protobuf:"bytes,2,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` + // status is the status of the enrollment. + Status ProjectEnrollmentStatus `protobuf:"varint,4,opt,name=status,proto3,enum=regen.ecocredit.v1.ProjectEnrollmentStatus" json:"status,omitempty"` + // application_metadata is any arbitrary metadata set by the project + // admin related to its application to the credit class. + ApplicationMetadata string `protobuf:"bytes,5,opt,name=application_metadata,json=applicationMetadata,proto3" json:"application_metadata,omitempty"` + // enrollment_metadata is any arbitrary metadata set by the credit class + // admin evaluating the project's application to the credit class. + EnrollmentMetadata string `protobuf:"bytes,6,opt,name=enrollment_metadata,json=enrollmentMetadata,proto3" json:"enrollment_metadata,omitempty"` +} + +func (m *EnrollmentInfo) Reset() { *m = EnrollmentInfo{} } +func (m *EnrollmentInfo) String() string { return proto.CompactTextString(m) } +func (*EnrollmentInfo) ProtoMessage() {} +func (*EnrollmentInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_c85efa417eafb74b, []int{60} +} +func (m *EnrollmentInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EnrollmentInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EnrollmentInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EnrollmentInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnrollmentInfo.Merge(m, src) +} +func (m *EnrollmentInfo) XXX_Size() int { + return m.Size() +} +func (m *EnrollmentInfo) XXX_DiscardUnknown() { + xxx_messageInfo_EnrollmentInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_EnrollmentInfo proto.InternalMessageInfo + +func (m *EnrollmentInfo) GetProjectId() string { + if m != nil { + return m.ProjectId + } + return "" +} + +func (m *EnrollmentInfo) GetClassId() string { + if m != nil { + return m.ClassId + } + return "" +} + +func (m *EnrollmentInfo) GetStatus() ProjectEnrollmentStatus { + if m != nil { + return m.Status + } + return ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_UNSPECIFIED +} + +func (m *EnrollmentInfo) GetApplicationMetadata() string { + if m != nil { + return m.ApplicationMetadata + } + return "" +} + +func (m *EnrollmentInfo) GetEnrollmentMetadata() string { + if m != nil { + return m.EnrollmentMetadata + } + return "" +} + func init() { proto.RegisterType((*QueryClassesRequest)(nil), "regen.ecocredit.v1.QueryClassesRequest") proto.RegisterType((*QueryClassesResponse)(nil), "regen.ecocredit.v1.QueryClassesResponse") @@ -3318,173 +3413,179 @@ func init() { proto.RegisterType((*QueryProjectEnrollmentResponse)(nil), "regen.ecocredit.v1.QueryProjectEnrollmentResponse") proto.RegisterType((*QueryProjectEnrollmentsRequest)(nil), "regen.ecocredit.v1.QueryProjectEnrollmentsRequest") proto.RegisterType((*QueryProjectEnrollmentsResponse)(nil), "regen.ecocredit.v1.QueryProjectEnrollmentsResponse") + proto.RegisterType((*EnrollmentInfo)(nil), "regen.ecocredit.v1.EnrollmentInfo") } func init() { proto.RegisterFile("regen/ecocredit/v1/query.proto", fileDescriptor_c85efa417eafb74b) } var fileDescriptor_c85efa417eafb74b = []byte{ - // 2574 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5b, 0xdb, 0x8f, 0x1c, 0x47, - 0xd5, 0x77, 0x8d, 0xbd, 0xbb, 0xb3, 0x67, 0xd7, 0x6b, 0xa7, 0x7c, 0xf9, 0xd6, 0x13, 0x7b, 0x6c, - 0x77, 0x6c, 0xef, 0xfa, 0x32, 0xd3, 0xde, 0x8b, 0xf3, 0x91, 0xc4, 0xc4, 0xec, 0xda, 0xc4, 0x2c, - 0x4f, 0xce, 0x10, 0x19, 0x65, 0xc1, 0x59, 0x7a, 0xa6, 0x6b, 0xd7, 0xed, 0xcc, 0x76, 0x8f, 0xbb, - 0x7b, 0xed, 0x2c, 0xab, 0x25, 0x01, 0x29, 0x09, 0x4f, 0x10, 0x11, 0x84, 0xf2, 0x12, 0x71, 0x11, - 0x3c, 0xc0, 0x03, 0x12, 0x09, 0x12, 0x42, 0x7e, 0x40, 0x08, 0x09, 0xf1, 0x68, 0x29, 0x3c, 0x70, - 0x79, 0x41, 0x36, 0x12, 0xfc, 0x19, 0x68, 0xaa, 0x4e, 0xf5, 0x6d, 0xba, 0xab, 0x7b, 0xc2, 0x60, - 0xed, 0x93, 0xb7, 0x6b, 0xce, 0xa9, 0xfa, 0xfd, 0x4e, 0x9d, 0x3a, 0x75, 0xea, 0x1c, 0x19, 0xaa, - 0x2e, 0x5b, 0x63, 0xb6, 0xce, 0x5a, 0x4e, 0xcb, 0x65, 0xa6, 0xe5, 0xeb, 0xf7, 0x66, 0xf4, 0xbb, - 0x1b, 0xcc, 0xdd, 0xac, 0x77, 0x5c, 0xc7, 0x77, 0x28, 0xe5, 0xbf, 0xd7, 0x83, 0xdf, 0xeb, 0xf7, - 0x66, 0x2a, 0xe7, 0x5a, 0x8e, 0xb7, 0xee, 0x78, 0x7a, 0xd3, 0xf0, 0x98, 0x10, 0xd6, 0xef, 0xcd, - 0x34, 0x99, 0x6f, 0xcc, 0xe8, 0x1d, 0x63, 0xcd, 0xb2, 0x0d, 0xdf, 0x72, 0x6c, 0xa1, 0x5f, 0xa9, - 0x46, 0x65, 0xa5, 0x54, 0xcb, 0xb1, 0xe4, 0xef, 0x47, 0xd7, 0x1c, 0x67, 0xad, 0xcd, 0x74, 0xa3, - 0x63, 0xe9, 0x86, 0x6d, 0x3b, 0x3e, 0x57, 0xf6, 0xf0, 0xd7, 0xe3, 0xf8, 0x2b, 0xff, 0x6a, 0x6e, - 0xac, 0xea, 0xbe, 0xb5, 0xce, 0x3c, 0xdf, 0x58, 0xef, 0xc8, 0xe9, 0x53, 0xe0, 0x7b, 0xbe, 0xe1, - 0x33, 0xc5, 0xef, 0xfe, 0x66, 0x87, 0xe1, 0x02, 0xda, 0x2d, 0x38, 0xf0, 0x72, 0x97, 0xc0, 0xd5, - 0xb6, 0xe1, 0x79, 0xcc, 0x6b, 0xb0, 0xbb, 0x1b, 0xcc, 0xf3, 0xe9, 0x4b, 0x00, 0x21, 0x93, 0x49, - 0x72, 0x82, 0x4c, 0x8f, 0xcd, 0x9e, 0xa9, 0x0b, 0x2a, 0xf5, 0x2e, 0x95, 0xba, 0xb0, 0x11, 0x12, - 0xaa, 0xdf, 0x30, 0xd6, 0x18, 0xea, 0x36, 0x22, 0x9a, 0xda, 0x07, 0x04, 0x0e, 0xc6, 0xe7, 0xf7, - 0x3a, 0x8e, 0xed, 0x31, 0xfa, 0xff, 0x30, 0xd2, 0x12, 0x43, 0x93, 0xe4, 0xc4, 0xee, 0xe9, 0xb1, - 0xd9, 0x63, 0xf5, 0x5e, 0x43, 0xd7, 0xb9, 0xd6, 0x92, 0xbd, 0xea, 0x34, 0xa4, 0x34, 0xbd, 0x1e, - 0x43, 0x56, 0xe2, 0xc8, 0xa6, 0x72, 0x91, 0x89, 0x55, 0x63, 0xd0, 0xbe, 0x0e, 0x95, 0x28, 0xb2, - 0xc5, 0xcd, 0x05, 0x73, 0xdd, 0xb2, 0xa5, 0x01, 0x0e, 0xc2, 0x90, 0xd1, 0xfd, 0xe6, 0xdc, 0x47, - 0x1b, 0xe2, 0x23, 0x61, 0x96, 0xd2, 0xa7, 0x36, 0xcb, 0x0f, 0x09, 0x3c, 0x9d, 0xba, 0xf8, 0x8e, - 0xb1, 0x4e, 0x1d, 0x9e, 0x0a, 0x01, 0x4a, 0xa3, 0x1c, 0x81, 0x32, 0x5f, 0x68, 0xc5, 0x32, 0xd1, - 0x2e, 0x62, 0xe1, 0x25, 0x53, 0x5b, 0x02, 0x1a, 0x95, 0x47, 0x1e, 0x73, 0x30, 0xc4, 0x05, 0xd0, - 0x83, 0x72, 0x58, 0x08, 0x59, 0x6d, 0x1b, 0x26, 0xc3, 0xa9, 0x96, 0x3c, 0x6f, 0x83, 0xb9, 0x05, - 0x10, 0x0c, 0x6c, 0x6f, 0xbe, 0x01, 0x47, 0x52, 0x96, 0x47, 0x42, 0x93, 0x30, 0x62, 0x89, 0x21, - 0xbe, 0x31, 0xa3, 0x0d, 0xf9, 0x39, 0x38, 0xcb, 0xbf, 0x86, 0x27, 0xe6, 0x86, 0xeb, 0xdc, 0x61, - 0x2d, 0x7f, 0xe0, 0x47, 0xf2, 0x43, 0x02, 0x87, 0x12, 0x0b, 0x20, 0xb9, 0x17, 0xa0, 0xdc, 0xc1, - 0x31, 0x74, 0xbb, 0xe3, 0x69, 0x1b, 0x86, 0x7a, 0x7c, 0xcb, 0x02, 0x85, 0xc1, 0xf1, 0x7f, 0x4b, - 0x9e, 0x0d, 0x89, 0x6f, 0xb1, 0xa8, 0x13, 0x0e, 0xcc, 0x05, 0x7e, 0x4a, 0xe0, 0x68, 0x3a, 0x84, - 0x1d, 0x65, 0xa9, 0xef, 0x10, 0x38, 0x99, 0x80, 0xd9, 0x60, 0xab, 0xcc, 0x65, 0x76, 0x8b, 0x2d, - 0x99, 0xd2, 0x5e, 0x27, 0x61, 0xdc, 0x95, 0xa3, 0xa1, 0xcd, 0xc6, 0xdc, 0x50, 0x72, 0x60, 0x76, - 0xfb, 0x05, 0x01, 0x4d, 0x05, 0x68, 0x47, 0x59, 0x6f, 0xab, 0xc7, 0xcd, 0x9e, 0xe0, 0x05, 0x90, - 0xe2, 0x61, 0xf1, 0x1b, 0x60, 0x67, 0xd8, 0x68, 0x1e, 0xb3, 0x03, 0x5c, 0x46, 0xda, 0xe6, 0x18, - 0x00, 0xae, 0x15, 0x3a, 0xd4, 0x28, 0x8e, 0x2c, 0x99, 0xda, 0xcb, 0xf1, 0x08, 0x16, 0x70, 0x7a, - 0x0e, 0x46, 0x50, 0x08, 0xc3, 0x57, 0x2e, 0x25, 0x29, 0x1f, 0xa4, 0x29, 0x8b, 0x86, 0xdf, 0xba, - 0xfd, 0x3f, 0x4c, 0x53, 0x82, 0xf9, 0xc3, 0x8b, 0xb8, 0x29, 0x86, 0x54, 0x17, 0x31, 0xd7, 0x12, - 0x80, 0x51, 0x7a, 0x70, 0x5b, 0xb0, 0x8d, 0x6e, 0x8a, 0xc8, 0x16, 0x37, 0xc5, 0x95, 0x24, 0x2d, - 0x70, 0x18, 0x86, 0xc5, 0x0d, 0x84, 0xdb, 0x80, 0x5f, 0x03, 0x73, 0xd4, 0x1f, 0x49, 0x47, 0xed, - 0x59, 0x7f, 0xc7, 0x58, 0xe8, 0x4d, 0x4c, 0xe4, 0x02, 0x84, 0x4f, 0xfa, 0xba, 0x78, 0xbb, 0xc7, - 0x46, 0x7d, 0x9d, 0x97, 0x81, 0xe1, 0xf8, 0x31, 0x81, 0x63, 0x19, 0x38, 0x76, 0xcc, 0x66, 0x05, - 0x99, 0x6f, 0x72, 0xb7, 0x76, 0x0c, 0xc2, 0x79, 0xcc, 0x7c, 0xf9, 0x1a, 0x72, 0x07, 0x8f, 0xc3, - 0x18, 0x5f, 0x68, 0xc5, 0x64, 0xb6, 0xb3, 0x8e, 0x5b, 0x08, 0x7c, 0xe8, 0x5a, 0x77, 0x24, 0xc8, - 0x7f, 0x51, 0x2b, 0xcc, 0x7f, 0xb9, 0x8c, 0x2a, 0xff, 0x0d, 0xb9, 0x08, 0x59, 0xed, 0x46, 0x10, - 0xeb, 0xda, 0x86, 0xdd, 0x92, 0x3b, 0xdd, 0x4d, 0x3d, 0x0d, 0xd3, 0x74, 0x19, 0x66, 0xd3, 0xa3, - 0x0d, 0xf9, 0x99, 0x04, 0x57, 0xea, 0x01, 0x77, 0x33, 0x88, 0x6e, 0x38, 0x23, 0xc2, 0x7b, 0xb1, - 0x6b, 0x6c, 0x3e, 0x84, 0x00, 0x4f, 0x65, 0x02, 0x44, 0x55, 0x69, 0x73, 0xfe, 0xa1, 0xbd, 0x11, - 0x9f, 0xd7, 0xcb, 0x87, 0x3a, 0x28, 0x57, 0xff, 0x89, 0x4c, 0x62, 0xc3, 0xa5, 0x91, 0xd3, 0xe7, - 0xa0, 0x8c, 0xf0, 0xa4, 0x07, 0x15, 0x23, 0x15, 0x68, 0x0d, 0xce, 0x93, 0xde, 0x09, 0x7d, 0x5d, - 0x4c, 0xbd, 0xd8, 0x9f, 0x53, 0x0d, 0xcc, 0x5a, 0x3f, 0x0f, 0x03, 0x54, 0x02, 0xc8, 0xce, 0x33, - 0x9a, 0x01, 0xff, 0xc7, 0xa1, 0x2e, 0xb4, 0xdb, 0x49, 0xb7, 0x1a, 0xd4, 0x6d, 0xff, 0x33, 0x82, - 0x2f, 0xcc, 0xd8, 0x1a, 0x3b, 0xcf, 0x14, 0x97, 0x30, 0xa6, 0x7c, 0x69, 0xa3, 0xd3, 0x69, 0x6f, - 0x16, 0x0e, 0x45, 0xef, 0x11, 0x0c, 0x20, 0x52, 0x0f, 0x99, 0x4d, 0xc1, 0x3e, 0xdf, 0x35, 0x4c, - 0xa3, 0xd9, 0x66, 0x2b, 0xc6, 0xba, 0xb3, 0x61, 0xfb, 0xa8, 0x3c, 0x21, 0x87, 0x17, 0xf8, 0x28, - 0x3d, 0x0d, 0x13, 0x2e, 0xf3, 0x2d, 0x97, 0x99, 0x52, 0x4e, 0x84, 0x94, 0xbd, 0x38, 0x8a, 0x62, - 0x67, 0x61, 0x7f, 0xab, 0xcb, 0xb8, 0xdd, 0x0e, 0x05, 0x77, 0x73, 0xc1, 0x7d, 0xc1, 0xb8, 0x10, - 0xd5, 0x8e, 0xe0, 0xa6, 0x5e, 0xe5, 0xf6, 0x7b, 0x65, 0xb3, 0x13, 0x6c, 0xaa, 0x76, 0x4b, 0xbe, - 0xf6, 0xa3, 0x3f, 0x21, 0xe2, 0x05, 0x18, 0x17, 0x16, 0x5f, 0xe1, 0x25, 0x2b, 0xdc, 0x8f, 0x6a, - 0x6a, 0x15, 0x21, 0x50, 0x6f, 0x8c, 0xb5, 0xc2, 0xa9, 0xb4, 0x83, 0x68, 0xc3, 0x1b, 0x86, 0x6b, - 0xac, 0x07, 0x8b, 0x2e, 0xc9, 0xbc, 0x16, 0x47, 0x71, 0xbd, 0x59, 0x18, 0xee, 0xf0, 0x11, 0x74, - 0xae, 0x4a, 0x6a, 0x7e, 0x2a, 0x74, 0x50, 0x52, 0xbb, 0x0c, 0x87, 0x13, 0xf8, 0xe5, 0x46, 0x69, - 0x30, 0x6e, 0x34, 0x9b, 0x2e, 0xbb, 0x67, 0x85, 0x0e, 0x3b, 0xda, 0x88, 0x8d, 0x69, 0xcb, 0x3d, - 0x86, 0x09, 0xc0, 0x5c, 0x81, 0xb1, 0x08, 0x79, 0x44, 0x94, 0xc7, 0x1d, 0x42, 0xee, 0xda, 0x16, - 0x8c, 0x06, 0xb5, 0x15, 0x3a, 0x01, 0xa5, 0x20, 0xf5, 0x28, 0x59, 0x66, 0xf8, 0xbc, 0x29, 0x45, - 0x9f, 0x37, 0x15, 0x28, 0xaf, 0x33, 0xdf, 0x30, 0x0d, 0xdf, 0xc0, 0xad, 0x0c, 0xbe, 0xe9, 0x05, - 0xa0, 0x11, 0x3c, 0x2b, 0x82, 0xc6, 0xe4, 0x1e, 0x2e, 0xb5, 0x3f, 0x5c, 0x76, 0x81, 0x8f, 0x6b, - 0xbf, 0x22, 0x30, 0x16, 0xc9, 0xe4, 0x0b, 0xae, 0x1f, 0x4d, 0xd6, 0x76, 0xc7, 0x93, 0x35, 0x0d, - 0xc6, 0xef, 0x6c, 0xb8, 0x96, 0x67, 0x5a, 0x2d, 0x6e, 0x4d, 0xb1, 0x70, 0x6c, 0x2c, 0x06, 0x7f, - 0x28, 0x01, 0x3f, 0xf9, 0x0c, 0x1e, 0xee, 0x79, 0x06, 0x6b, 0x0f, 0x4a, 0x30, 0x1a, 0xdc, 0xc6, - 0x99, 0x99, 0x75, 0x3c, 0x99, 0x2b, 0x25, 0x93, 0xb9, 0x83, 0x30, 0x24, 0x0e, 0xa6, 0xc0, 0x2f, - 0x3e, 0x62, 0xc8, 0xf6, 0x24, 0x90, 0x3d, 0x07, 0xe0, 0xf9, 0x86, 0xeb, 0xaf, 0x98, 0x86, 0xcf, - 0x38, 0xee, 0xae, 0xe7, 0x89, 0xc2, 0x6f, 0x5d, 0x16, 0x7e, 0xeb, 0xaf, 0xc8, 0xc2, 0x6f, 0x63, - 0x94, 0x4b, 0x5f, 0x33, 0x7c, 0x46, 0x2f, 0x41, 0x99, 0xd9, 0xa6, 0x50, 0x1c, 0xce, 0x55, 0x1c, - 0x61, 0xb6, 0xc9, 0xd5, 0xae, 0xc0, 0xde, 0x2e, 0x99, 0xee, 0x21, 0x15, 0xba, 0x23, 0xb9, 0xba, - 0xe3, 0x52, 0x81, 0x4f, 0x40, 0x61, 0x8f, 0xd3, 0x61, 0xf6, 0x64, 0xf9, 0x04, 0x99, 0x2e, 0x37, - 0xf8, 0xdf, 0xda, 0x1f, 0x09, 0xec, 0x4f, 0x46, 0xc5, 0xff, 0x22, 0x69, 0x49, 0x0b, 0x57, 0xbb, - 0x0b, 0x86, 0xab, 0x3d, 0x69, 0xe1, 0x6a, 0x0a, 0xf6, 0x31, 0xaf, 0xe5, 0x3a, 0xf7, 0x43, 0x39, - 0xe1, 0x23, 0x13, 0x72, 0x18, 0x83, 0xd5, 0x33, 0x58, 0x55, 0xe1, 0x87, 0xe7, 0xaa, 0xcb, 0x0c, - 0xdf, 0x71, 0x17, 0xda, 0x6d, 0xe7, 0x7e, 0xdb, 0xf2, 0x64, 0x4a, 0xaf, 0xbd, 0x88, 0x95, 0x8e, - 0x0c, 0xa1, 0xb0, 0x5c, 0xc8, 0xec, 0x2e, 0x54, 0xe1, 0xfa, 0xe5, 0x86, 0xfc, 0xd4, 0xee, 0xc0, - 0x09, 0x79, 0x05, 0x75, 0x97, 0x8e, 0x4e, 0x33, 0xf0, 0xfb, 0xee, 0x7d, 0x59, 0x27, 0x4a, 0x5f, - 0x0c, 0xb1, 0x9e, 0x86, 0x09, 0x71, 0xf6, 0x5a, 0xf8, 0x0b, 0x56, 0x38, 0xf7, 0xb6, 0xa2, 0xe2, - 0x83, 0xbb, 0xdd, 0x0e, 0x47, 0x3b, 0x03, 0x2f, 0x31, 0x89, 0x5c, 0xbb, 0x86, 0x99, 0x5d, 0x38, - 0x8e, 0x00, 0xcf, 0xc3, 0xee, 0x55, 0x26, 0x03, 0xe1, 0x91, 0xd8, 0x92, 0x72, 0xb1, 0xab, 0x8e, - 0x65, 0x37, 0xba, 0x52, 0xda, 0x49, 0x38, 0x1e, 0xa5, 0xbc, 0xe8, 0x5a, 0xe6, 0x1a, 0xbb, 0x7a, - 0xdb, 0xb0, 0xec, 0xe0, 0x12, 0xb8, 0x19, 0xdf, 0x82, 0xb8, 0x48, 0x70, 0x23, 0x1c, 0x32, 0xc4, - 0xcf, 0x2b, 0x4d, 0xfe, 0xfb, 0x4a, 0x8b, 0x0b, 0xa0, 0x6d, 0x0e, 0x18, 0xbd, 0xba, 0xda, 0xab, - 0xf8, 0x0a, 0xc3, 0xf0, 0xf7, 0x79, 0xdb, 0x75, 0xda, 0xed, 0x75, 0x66, 0x17, 0x7d, 0x0e, 0x46, - 0x83, 0x60, 0x29, 0x5e, 0x65, 0x6f, 0x43, 0x35, 0x6b, 0x6a, 0x04, 0xfc, 0x45, 0xd8, 0x2b, 0xe7, - 0x8e, 0x56, 0xde, 0x4f, 0x2b, 0x2a, 0x2d, 0x91, 0x59, 0xc6, 0x51, 0x97, 0xdb, 0x5e, 0x7b, 0x97, - 0x64, 0x2d, 0xe7, 0x3d, 0xe1, 0x97, 0xed, 0xc7, 0x04, 0xb7, 0x33, 0x0d, 0x09, 0x32, 0xbf, 0x0e, - 0x63, 0x2c, 0x1c, 0xc6, 0x5c, 0xa1, 0x20, 0xef, 0xa8, 0xe6, 0xc0, 0x3c, 0x7c, 0xf6, 0xf7, 0xe7, - 0x60, 0x88, 0xa3, 0xa6, 0xdf, 0x24, 0x30, 0x82, 0xad, 0x1e, 0x3a, 0x95, 0x06, 0x29, 0xa5, 0x07, - 0x57, 0x99, 0xce, 0x17, 0x14, 0x8b, 0x6a, 0xcf, 0x7c, 0xeb, 0x93, 0x7f, 0xbe, 0x5f, 0x3a, 0x46, - 0x9f, 0xd6, 0x53, 0xba, 0x7d, 0xb2, 0x35, 0xf4, 0x67, 0x02, 0x13, 0xf1, 0x76, 0x13, 0xad, 0xe7, - 0xad, 0x10, 0xaf, 0x89, 0x56, 0xf4, 0xc2, 0xf2, 0x08, 0xcc, 0xe0, 0xc0, 0xbe, 0x42, 0x2f, 0x28, - 0x80, 0xd5, 0x9a, 0x9b, 0x35, 0x7e, 0xfb, 0xeb, 0x5b, 0xfc, 0x9f, 0xed, 0xe5, 0xf3, 0xf4, 0xac, - 0x42, 0x5e, 0x8f, 0x09, 0xd3, 0x5f, 0x12, 0x18, 0xe2, 0xab, 0xd3, 0xd3, 0x6a, 0x74, 0x92, 0xc4, - 0x99, 0x3c, 0x31, 0xc4, 0x7e, 0x93, 0x63, 0xbf, 0x41, 0x4f, 0x65, 0x62, 0xd1, 0xb7, 0xe4, 0x39, - 0xdd, 0x5e, 0x9e, 0xa6, 0x67, 0x54, 0x98, 0x43, 0x49, 0xfa, 0x09, 0x81, 0xf1, 0x68, 0x6f, 0x89, - 0x5e, 0x50, 0x03, 0x8a, 0x77, 0xc0, 0x2a, 0xb5, 0x82, 0xd2, 0xc8, 0x62, 0x95, 0xb3, 0xf8, 0x9a, - 0x62, 0x07, 0x6a, 0xd8, 0xc1, 0x8a, 0xb2, 0xb9, 0x48, 0xeb, 0xc5, 0xd8, 0xe8, 0xb2, 0xfd, 0xf5, - 0x36, 0x81, 0xb2, 0xac, 0x65, 0xd3, 0x6c, 0xcf, 0x4d, 0x34, 0xb5, 0x2a, 0x67, 0x0b, 0x48, 0x22, - 0x93, 0x53, 0x9c, 0x49, 0x95, 0x1e, 0x4d, 0x43, 0x16, 0x94, 0xbe, 0xbf, 0x5f, 0x82, 0x7d, 0x89, - 0xae, 0x0d, 0xd5, 0x73, 0x17, 0x89, 0xd7, 0x0c, 0x2b, 0x17, 0x8b, 0x2b, 0x20, 0xb8, 0x0f, 0x09, - 0x47, 0xf7, 0x03, 0x42, 0x2f, 0xaa, 0xe0, 0x75, 0x7d, 0xbd, 0xc7, 0x75, 0x74, 0x5a, 0x53, 0xe9, - 0xf4, 0xfa, 0xda, 0x0c, 0xd5, 0x0b, 0xee, 0x4e, 0x60, 0x96, 0x77, 0x4b, 0x70, 0x28, 0xb5, 0x29, - 0x43, 0x2f, 0x15, 0xe0, 0xda, 0xdb, 0x55, 0xaa, 0x3c, 0xdb, 0xaf, 0x1a, 0x1a, 0xea, 0x4d, 0x6e, - 0xa7, 0x4d, 0xfa, 0x42, 0x9e, 0x99, 0x82, 0xc4, 0xbc, 0x66, 0x99, 0xfa, 0x56, 0x34, 0x75, 0xdf, - 0x5e, 0x7e, 0x9e, 0x7e, 0x46, 0x69, 0x31, 0x85, 0x2e, 0xfd, 0x2b, 0x89, 0x3a, 0x88, 0x88, 0x83, - 0x45, 0x1c, 0x24, 0x16, 0x08, 0x2f, 0x16, 0x57, 0x40, 0xde, 0x2d, 0xce, 0xfb, 0x96, 0x7a, 0xab, - 0x7b, 0x43, 0xe1, 0x05, 0x7a, 0x4e, 0xc9, 0x34, 0x1e, 0x0b, 0x1f, 0x10, 0x18, 0x41, 0x00, 0x8a, - 0x6b, 0x26, 0x5e, 0x9c, 0xae, 0x4c, 0xe7, 0x0b, 0x22, 0x87, 0x5b, 0x9c, 0xc3, 0x97, 0xe9, 0xb4, - 0x02, 0x92, 0xbe, 0x15, 0xe6, 0x03, 0x99, 0x91, 0x3c, 0x80, 0x1f, 0x15, 0xe6, 0x97, 0x24, 0x56, - 0x85, 0x15, 0xe8, 0xe3, 0x1d, 0x20, 0x05, 0xfa, 0x44, 0x2b, 0x47, 0x7d, 0x49, 0xca, 0x2a, 0xf2, - 0xdf, 0x09, 0xec, 0x4b, 0x74, 0x3a, 0x14, 0xde, 0x91, 0xde, 0x93, 0x51, 0x78, 0x47, 0x46, 0x13, - 0x45, 0x63, 0x1c, 0xdb, 0x4a, 0x7a, 0xd4, 0x45, 0x6c, 0x5d, 0xe7, 0x10, 0xd1, 0x56, 0xdf, 0x12, - 0xff, 0x6e, 0x2f, 0xd7, 0xe8, 0x79, 0x85, 0x86, 0x9e, 0x10, 0xa7, 0x7f, 0x23, 0x30, 0x11, 0xaf, - 0xbb, 0x2b, 0x52, 0x80, 0xd4, 0x76, 0x4a, 0x45, 0x2f, 0x2c, 0x8f, 0xd4, 0xd6, 0x38, 0x35, 0x23, - 0x3d, 0x64, 0x45, 0xa8, 0xf5, 0x44, 0xb9, 0x7a, 0xfa, 0x9d, 0x25, 0xb9, 0x25, 0xe5, 0xe9, 0xbf, - 0xe5, 0xfb, 0x33, 0xd2, 0xf8, 0xa0, 0x05, 0xb6, 0x22, 0x71, 0x1c, 0x66, 0xfa, 0xd0, 0x40, 0x8a, - 0x0e, 0xa7, 0x68, 0xd1, 0xb9, 0x1c, 0x8a, 0xa9, 0x47, 0x64, 0x36, 0xfd, 0xc6, 0x90, 0x34, 0xd3, - 0x74, 0xe8, 0xaf, 0x09, 0x0c, 0x71, 0x34, 0x8a, 0x9c, 0x27, 0x5a, 0x69, 0x56, 0xe4, 0x3c, 0xb1, - 0x3a, 0xb0, 0xf6, 0x55, 0xce, 0xe4, 0x26, 0x9d, 0xca, 0x84, 0xa4, 0x6f, 0x45, 0x5e, 0xed, 0x99, - 0x07, 0x5c, 0xa2, 0x8f, 0x09, 0xd3, 0x0f, 0x4a, 0xdd, 0x03, 0xce, 0x8b, 0x03, 0xca, 0x03, 0x1e, - 0x6d, 0x7b, 0x28, 0x0f, 0x78, 0xac, 0x9b, 0xa1, 0xfd, 0x56, 0xdc, 0xc1, 0x1f, 0x91, 0xac, 0x8d, - 0xe0, 0xe2, 0x71, 0x4c, 0xdd, 0xd0, 0xc9, 0xeb, 0x11, 0xdb, 0xcb, 0x9f, 0x4d, 0xbf, 0x93, 0x52, - 0xa9, 0x84, 0x93, 0x05, 0xea, 0x97, 0xe9, 0xf3, 0x8a, 0x55, 0xbd, 0x50, 0x32, 0xcd, 0x8e, 0xf4, - 0xbb, 0x04, 0xca, 0xb2, 0x14, 0x4d, 0x73, 0x29, 0x17, 0x48, 0x9f, 0x92, 0x75, 0x6d, 0xad, 0xce, - 0x8d, 0x93, 0x91, 0xa6, 0xf6, 0xa2, 0xa4, 0xff, 0xe2, 0x91, 0x30, 0xd6, 0x2e, 0x50, 0x46, 0xc2, - 0xb4, 0x0e, 0x87, 0x32, 0x12, 0xa6, 0x76, 0x22, 0xb4, 0xbb, 0x1c, 0xe6, 0xeb, 0xca, 0x2d, 0xe4, - 0x87, 0x29, 0xcd, 0x1b, 0xe7, 0xe9, 0x6c, 0xdf, 0x5b, 0xe8, 0xd1, 0x8f, 0x08, 0x8c, 0x45, 0x3a, - 0x01, 0xf4, 0x7c, 0x26, 0xe8, 0xde, 0x9e, 0x44, 0xe5, 0x42, 0x31, 0x61, 0x64, 0xf7, 0x05, 0xce, - 0x6e, 0x91, 0x9e, 0x48, 0x83, 0x69, 0xb4, 0xdb, 0x35, 0x09, 0x6a, 0x39, 0x23, 0xcf, 0x0d, 0x40, - 0xff, 0x8e, 0xc0, 0xb0, 0xa8, 0xef, 0xd3, 0xec, 0xc3, 0x1d, 0x6b, 0x1c, 0x54, 0xa6, 0x72, 0xe5, - 0x10, 0xa5, 0xc9, 0x51, 0xbe, 0x96, 0x7e, 0xcf, 0x7b, 0x5c, 0x36, 0x61, 0xf8, 0x9c, 0x20, 0x16, - 0x37, 0xbc, 0x98, 0x81, 0x7e, 0x8f, 0xc0, 0x58, 0xa4, 0xe8, 0xaf, 0x30, 0x7b, 0x6f, 0xd7, 0x40, - 0x61, 0xf6, 0x94, 0x3e, 0x82, 0x36, 0xcd, 0x09, 0x69, 0xe9, 0x66, 0x17, 0x7f, 0xd5, 0x78, 0x87, - 0x81, 0xbe, 0x45, 0x60, 0x58, 0x14, 0xf8, 0x15, 0x66, 0x8d, 0xf5, 0x12, 0x14, 0x66, 0x8d, 0x77, - 0x17, 0xb4, 0xd3, 0x1c, 0xc5, 0x51, 0x5a, 0x49, 0x4d, 0x89, 0xb8, 0xec, 0xb7, 0x4b, 0x84, 0x3e, - 0x24, 0x00, 0x21, 0x09, 0x7a, 0xae, 0x00, 0x53, 0x09, 0xe5, 0x7c, 0x21, 0x59, 0x84, 0x63, 0x71, - 0x38, 0xad, 0x8c, 0x97, 0x5e, 0x68, 0x14, 0x7d, 0x2b, 0xda, 0xb1, 0xc8, 0x7e, 0x7d, 0x44, 0xcc, - 0x98, 0x50, 0xe9, 0xe6, 0xa5, 0x87, 0x52, 0x0b, 0xa5, 0x8a, 0xd7, 0x87, 0xaa, 0xfa, 0xaa, 0x78, - 0x7d, 0x28, 0xeb, 0xb1, 0xda, 0x1c, 0xe7, 0x9c, 0x91, 0x35, 0x89, 0xd7, 0x30, 0x56, 0x3f, 0x6b, - 0x46, 0x80, 0xf1, 0x37, 0x04, 0x0e, 0xa6, 0x55, 0x4e, 0xe9, 0xbc, 0xea, 0xec, 0x67, 0x55, 0x75, - 0x2b, 0x97, 0xfa, 0xd4, 0x42, 0xe8, 0xb3, 0x1c, 0x7a, 0xc6, 0x7b, 0x00, 0xcb, 0x90, 0xb5, 0x18, - 0x05, 0x8f, 0xbe, 0x43, 0xa0, 0x2c, 0xcb, 0xa8, 0x34, 0xa7, 0x9c, 0x14, 0x56, 0x60, 0x15, 0xb7, - 0x4a, 0xb2, 0x26, 0x8b, 0x3e, 0x7d, 0x9c, 0x1e, 0xcb, 0x36, 0xe8, 0x2a, 0x63, 0xf4, 0x63, 0x02, - 0x07, 0x52, 0xca, 0xac, 0x74, 0x2e, 0xcf, 0x16, 0x29, 0x75, 0xdb, 0xca, 0x7c, 0x7f, 0x4a, 0x88, - 0x74, 0x86, 0x23, 0xcd, 0xc8, 0x57, 0xa4, 0xfd, 0x44, 0x8d, 0xb7, 0x26, 0x6a, 0xbc, 0xf4, 0x0f, - 0x04, 0x9e, 0xea, 0xa9, 0x15, 0xd2, 0x99, 0xbc, 0xf7, 0x52, 0x4f, 0xc1, 0xb7, 0x32, 0xdb, 0x8f, - 0x0a, 0xe2, 0xbd, 0xce, 0xf1, 0x2e, 0xd0, 0x2b, 0x45, 0x1f, 0x5b, 0x7a, 0xa4, 0x86, 0x19, 0xcd, - 0x8b, 0x1f, 0x10, 0xa0, 0xbd, 0x65, 0x53, 0xda, 0x07, 0xa6, 0xc0, 0xf2, 0x73, 0x7d, 0xe9, 0x20, - 0x91, 0xcb, 0x9c, 0xc8, 0xb3, 0x74, 0xfe, 0xd3, 0x10, 0x59, 0x7c, 0xf5, 0x4f, 0x8f, 0xaa, 0xe4, - 0xe1, 0xa3, 0x2a, 0xf9, 0xc7, 0xa3, 0x2a, 0x79, 0xef, 0x71, 0x75, 0xd7, 0xc3, 0xc7, 0xd5, 0x5d, - 0x7f, 0x79, 0x5c, 0xdd, 0xb5, 0x7c, 0x65, 0xcd, 0xf2, 0x6f, 0x6f, 0x34, 0xeb, 0x2d, 0x67, 0x5d, - 0xcc, 0x5c, 0xb3, 0x99, 0x7f, 0xdf, 0x71, 0x5f, 0xc7, 0xaf, 0x36, 0x33, 0xd7, 0x98, 0xab, 0xbf, - 0x11, 0x59, 0x90, 0xff, 0x1f, 0x0c, 0x11, 0xa1, 0xee, 0xcd, 0x34, 0x87, 0x79, 0x9b, 0x6b, 0xee, - 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x90, 0x55, 0x29, 0x02, 0x32, 0x00, 0x00, + // 2649 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5b, 0xdf, 0x6f, 0x1c, 0x57, + 0xf5, 0xcf, 0xdd, 0xc4, 0xf6, 0xfa, 0xd8, 0x71, 0xd2, 0x1b, 0x27, 0x5f, 0x67, 0x1b, 0x6f, 0x92, + 0x69, 0x12, 0x3b, 0x71, 0x76, 0x27, 0xfe, 0x91, 0x7e, 0x69, 0x1b, 0x1a, 0x6c, 0x87, 0x16, 0x3f, + 0x20, 0xa5, 0xdb, 0x2a, 0xa8, 0x86, 0xd4, 0xcc, 0xee, 0x5c, 0x3b, 0x93, 0xae, 0x67, 0x36, 0x33, + 0xe3, 0xa4, 0xc6, 0x32, 0x2d, 0x48, 0x2d, 0x3c, 0x41, 0x45, 0x11, 0xea, 0x4b, 0xc5, 0x0f, 0xc1, + 0x03, 0x3c, 0x20, 0x54, 0x40, 0x08, 0xe5, 0x01, 0x21, 0x24, 0xc4, 0x63, 0xa4, 0xf2, 0xc0, 0x8f, + 0x17, 0x94, 0x20, 0xc1, 0x3b, 0xff, 0x00, 0xda, 0x7b, 0xcf, 0x9d, 0x5f, 0x3b, 0x73, 0x77, 0x36, + 0x6c, 0x2b, 0x3f, 0x79, 0xe7, 0xce, 0x39, 0x73, 0x3f, 0x9f, 0x73, 0xcf, 0x3d, 0xf7, 0xdc, 0x73, + 0x64, 0x28, 0xbb, 0x6c, 0x83, 0xd9, 0x3a, 0x6b, 0x38, 0x0d, 0x97, 0x99, 0x96, 0xaf, 0xdf, 0x9d, + 0xd5, 0xef, 0x6c, 0x31, 0x77, 0xbb, 0xda, 0x72, 0x1d, 0xdf, 0xa1, 0x94, 0xbf, 0xaf, 0x06, 0xef, + 0xab, 0x77, 0x67, 0x4b, 0x17, 0x1a, 0x8e, 0xb7, 0xe9, 0x78, 0x7a, 0xdd, 0xf0, 0x98, 0x10, 0xd6, + 0xef, 0xce, 0xd6, 0x99, 0x6f, 0xcc, 0xea, 0x2d, 0x63, 0xc3, 0xb2, 0x0d, 0xdf, 0x72, 0x6c, 0xa1, + 0x5f, 0x2a, 0x47, 0x65, 0xa5, 0x54, 0xc3, 0xb1, 0xe4, 0xfb, 0x13, 0x1b, 0x8e, 0xb3, 0xd1, 0x64, + 0xba, 0xd1, 0xb2, 0x74, 0xc3, 0xb6, 0x1d, 0x9f, 0x2b, 0x7b, 0xf8, 0xf6, 0x24, 0xbe, 0xe5, 0x4f, + 0xf5, 0xad, 0x75, 0xdd, 0xb7, 0x36, 0x99, 0xe7, 0x1b, 0x9b, 0x2d, 0xf9, 0xf9, 0x14, 0xf8, 0x9e, + 0x6f, 0xf8, 0x4c, 0xf1, 0xde, 0xdf, 0x6e, 0x31, 0x9c, 0x40, 0xbb, 0x09, 0x47, 0x5e, 0x6a, 0x13, + 0x58, 0x6e, 0x1a, 0x9e, 0xc7, 0xbc, 0x1a, 0xbb, 0xb3, 0xc5, 0x3c, 0x9f, 0xbe, 0x00, 0x10, 0x32, + 0x99, 0x20, 0xa7, 0xc8, 0xf4, 0xc8, 0xdc, 0xb9, 0xaa, 0xa0, 0x52, 0x6d, 0x53, 0xa9, 0x0a, 0x1b, + 0x21, 0xa1, 0xea, 0x75, 0x63, 0x83, 0xa1, 0x6e, 0x2d, 0xa2, 0xa9, 0xbd, 0x4f, 0x60, 0x3c, 0xfe, + 0x7d, 0xaf, 0xe5, 0xd8, 0x1e, 0xa3, 0xff, 0x0f, 0x43, 0x0d, 0x31, 0x34, 0x41, 0x4e, 0xed, 0x9f, + 0x1e, 0x99, 0x9b, 0xac, 0x76, 0x1a, 0xba, 0xca, 0xb5, 0x56, 0xec, 0x75, 0xa7, 0x26, 0xa5, 0xe9, + 0x8b, 0x31, 0x64, 0x05, 0x8e, 0x6c, 0xaa, 0x2b, 0x32, 0x31, 0x6b, 0x0c, 0xda, 0x57, 0xa0, 0x14, + 0x45, 0xb6, 0xb4, 0xbd, 0x68, 0x6e, 0x5a, 0xb6, 0x34, 0xc0, 0x38, 0x0c, 0x18, 0xed, 0x67, 0xce, + 0x7d, 0xb8, 0x26, 0x1e, 0x12, 0x66, 0x29, 0x3c, 0xb6, 0x59, 0xbe, 0x4f, 0xe0, 0xc9, 0xd4, 0xc9, + 0xf7, 0x8c, 0x75, 0xaa, 0xf0, 0x44, 0x08, 0x50, 0x1a, 0xe5, 0x38, 0x14, 0xf9, 0x44, 0x6b, 0x96, + 0x89, 0x76, 0x11, 0x13, 0xaf, 0x98, 0xda, 0x0a, 0xd0, 0xa8, 0x3c, 0xf2, 0x98, 0x87, 0x01, 0x2e, + 0x80, 0x1e, 0xd4, 0x85, 0x85, 0x90, 0xd5, 0x76, 0x61, 0x22, 0xfc, 0xd4, 0x8a, 0xe7, 0x6d, 0x31, + 0x37, 0x07, 0x82, 0xbe, 0xad, 0xcd, 0x57, 0xe1, 0x78, 0xca, 0xf4, 0x48, 0x68, 0x02, 0x86, 0x2c, + 0x31, 0xc4, 0x17, 0x66, 0xb8, 0x26, 0x1f, 0xfb, 0x67, 0xf9, 0xd7, 0x70, 0xc7, 0x5c, 0x77, 0x9d, + 0xdb, 0xac, 0xe1, 0xf7, 0x7d, 0x4b, 0x7e, 0x40, 0xe0, 0x68, 0x62, 0x02, 0x24, 0xf7, 0x1c, 0x14, + 0x5b, 0x38, 0x86, 0x6e, 0x77, 0x32, 0x6d, 0xc1, 0x50, 0x8f, 0x2f, 0x59, 0xa0, 0xd0, 0x3f, 0xfe, + 0x6f, 0xc9, 0xbd, 0x21, 0xf1, 0x2d, 0xe5, 0x75, 0xc2, 0xbe, 0xb9, 0xc0, 0x8f, 0x09, 0x9c, 0x48, + 0x87, 0xb0, 0xa7, 0x2c, 0xf5, 0x2d, 0x02, 0xa7, 0x13, 0x30, 0x6b, 0x6c, 0x9d, 0xb9, 0xcc, 0x6e, + 0xb0, 0x15, 0x53, 0xda, 0xeb, 0x34, 0x8c, 0xba, 0x72, 0x34, 0xb4, 0xd9, 0x88, 0x1b, 0x4a, 0xf6, + 0xcd, 0x6e, 0x3f, 0x23, 0xa0, 0xa9, 0x00, 0xed, 0x29, 0xeb, 0xed, 0x74, 0xb8, 0xd9, 0x27, 0x78, + 0x00, 0xa4, 0x78, 0x58, 0xfc, 0x04, 0xd8, 0x1b, 0x36, 0x5a, 0xc0, 0xec, 0x00, 0xa7, 0x91, 0xb6, + 0x99, 0x04, 0xc0, 0xb9, 0x42, 0x87, 0x1a, 0xc6, 0x91, 0x15, 0x53, 0x7b, 0x29, 0x1e, 0xc1, 0x02, + 0x4e, 0xcf, 0xc0, 0x10, 0x0a, 0x61, 0xf8, 0xea, 0x4a, 0x49, 0xca, 0x07, 0x69, 0xca, 0x92, 0xe1, + 0x37, 0x6e, 0x7d, 0x8c, 0x69, 0x4a, 0xf0, 0xfd, 0xf0, 0x20, 0xae, 0x8b, 0x21, 0xd5, 0x41, 0xcc, + 0xb5, 0x04, 0x60, 0x94, 0xee, 0xdf, 0x12, 0xec, 0xa2, 0x9b, 0x22, 0xb2, 0xa5, 0x6d, 0x71, 0x24, + 0x49, 0x0b, 0x1c, 0x83, 0x41, 0x71, 0x02, 0xe1, 0x32, 0xe0, 0x53, 0xdf, 0x1c, 0xf5, 0x07, 0xd2, + 0x51, 0x3b, 0xe6, 0xdf, 0x33, 0x16, 0x7a, 0x13, 0x13, 0xb9, 0x00, 0xe1, 0x27, 0x7d, 0x5c, 0xbc, + 0xdd, 0x61, 0xa3, 0x9e, 0xf6, 0x4b, 0xdf, 0x70, 0xfc, 0x90, 0xc0, 0x64, 0x06, 0x8e, 0x3d, 0xb3, + 0x58, 0x41, 0xe6, 0x9b, 0x5c, 0xad, 0x3d, 0x83, 0x70, 0x01, 0x33, 0x5f, 0x3e, 0x87, 0x5c, 0xc1, + 0x93, 0x30, 0xc2, 0x27, 0x5a, 0x33, 0x99, 0xed, 0x6c, 0xe2, 0x12, 0x02, 0x1f, 0xba, 0xd6, 0x1e, + 0x09, 0xf2, 0x5f, 0xd4, 0x0a, 0xf3, 0x5f, 0x2e, 0xa3, 0xca, 0x7f, 0x43, 0x2e, 0x42, 0x56, 0xbb, + 0x1e, 0xc4, 0xba, 0xa6, 0x61, 0x37, 0xe4, 0x4a, 0xb7, 0x53, 0x4f, 0xc3, 0x34, 0x5d, 0x86, 0xd9, + 0xf4, 0x70, 0x4d, 0x3e, 0x26, 0xc1, 0x15, 0x3a, 0xc0, 0xdd, 0x08, 0xa2, 0x1b, 0x7e, 0x11, 0xe1, + 0x3d, 0xdf, 0x36, 0x36, 0x1f, 0x42, 0x80, 0x67, 0x32, 0x01, 0xa2, 0xaa, 0xb4, 0x39, 0x7f, 0xd0, + 0xde, 0x88, 0x7f, 0xd7, 0xeb, 0x0e, 0xb5, 0x5f, 0xae, 0xfe, 0x23, 0x99, 0xc4, 0x86, 0x53, 0x23, + 0xa7, 0xcf, 0x40, 0x11, 0xe1, 0x49, 0x0f, 0xca, 0x47, 0x2a, 0xd0, 0xea, 0x9f, 0x27, 0xbd, 0x13, + 0xfa, 0xba, 0xf8, 0xf4, 0x52, 0x6f, 0x4e, 0xd5, 0x37, 0x6b, 0xfd, 0x34, 0x0c, 0x50, 0x09, 0x20, + 0x7b, 0xcf, 0x68, 0x06, 0xfc, 0x1f, 0x87, 0xba, 0xd8, 0x6c, 0x26, 0xdd, 0xaa, 0x5f, 0xa7, 0xfd, + 0x4f, 0x08, 0xde, 0x30, 0x63, 0x73, 0xec, 0x3d, 0x53, 0x5c, 0xc6, 0x98, 0xf2, 0xf2, 0x56, 0xab, + 0xd5, 0xdc, 0xce, 0x1d, 0x8a, 0xde, 0x25, 0x18, 0x40, 0xa4, 0x1e, 0x32, 0x9b, 0x82, 0x43, 0xbe, + 0x6b, 0x98, 0x46, 0xbd, 0xc9, 0xd6, 0x8c, 0x4d, 0x67, 0xcb, 0xf6, 0x51, 0x79, 0x4c, 0x0e, 0x2f, + 0xf2, 0x51, 0x7a, 0x16, 0xc6, 0x5c, 0xe6, 0x5b, 0x2e, 0x33, 0xa5, 0x9c, 0x08, 0x29, 0x07, 0x71, + 0x14, 0xc5, 0xce, 0xc3, 0xe1, 0x46, 0x9b, 0x71, 0xb3, 0x19, 0x0a, 0xee, 0xe7, 0x82, 0x87, 0x82, + 0x71, 0x21, 0xaa, 0x1d, 0xc7, 0x45, 0x5d, 0xe6, 0xf6, 0x7b, 0x65, 0xbb, 0x15, 0x2c, 0xaa, 0x76, + 0x53, 0xde, 0xf6, 0xa3, 0xaf, 0x10, 0xf1, 0x22, 0x8c, 0x0a, 0x8b, 0xaf, 0xf1, 0x92, 0x15, 0xae, + 0x47, 0x39, 0xb5, 0x8a, 0x10, 0xa8, 0xd7, 0x46, 0x1a, 0xe1, 0xa7, 0xb4, 0x71, 0xb4, 0xe1, 0x75, + 0xc3, 0x35, 0x36, 0x83, 0x49, 0x57, 0x64, 0x5e, 0x8b, 0xa3, 0x38, 0xdf, 0x1c, 0x0c, 0xb6, 0xf8, + 0x08, 0x3a, 0x57, 0x29, 0x35, 0x3f, 0x15, 0x3a, 0x28, 0xa9, 0x5d, 0x81, 0x63, 0x09, 0xfc, 0x72, + 0xa1, 0x34, 0x18, 0x35, 0xea, 0x75, 0x97, 0xdd, 0xb5, 0x42, 0x87, 0x1d, 0xae, 0xc5, 0xc6, 0xb4, + 0xd5, 0x0e, 0xc3, 0x04, 0x60, 0xae, 0xc2, 0x48, 0x84, 0x3c, 0x22, 0xea, 0xc6, 0x1d, 0x42, 0xee, + 0xda, 0x0e, 0x0c, 0x07, 0xb5, 0x15, 0x3a, 0x06, 0x85, 0x20, 0xf5, 0x28, 0x58, 0x66, 0x78, 0xbd, + 0x29, 0x44, 0xaf, 0x37, 0x25, 0x28, 0x6e, 0x32, 0xdf, 0x30, 0x0d, 0xdf, 0xc0, 0xa5, 0x0c, 0x9e, + 0xe9, 0x45, 0xa0, 0x11, 0x3c, 0x6b, 0x82, 0xc6, 0xc4, 0x01, 0x2e, 0x75, 0x38, 0x9c, 0x76, 0x91, + 0x8f, 0x6b, 0xbf, 0x26, 0x30, 0x12, 0xc9, 0xe4, 0x73, 0xce, 0x3f, 0x19, 0x49, 0xd6, 0xf8, 0xfc, + 0x4b, 0x85, 0x09, 0x12, 0x26, 0x6c, 0x1a, 0x8c, 0xde, 0xde, 0x72, 0x2d, 0xcf, 0xb4, 0x1a, 0xdc, + 0xa2, 0x62, 0xf2, 0xd8, 0x58, 0x8c, 0xc2, 0x40, 0x82, 0x42, 0xf2, 0x2a, 0x3c, 0xd8, 0x71, 0x15, + 0xd6, 0xee, 0x17, 0x60, 0x38, 0x38, 0x91, 0x33, 0xb3, 0xeb, 0x78, 0x42, 0x57, 0x48, 0x26, 0x74, + 0xe3, 0x30, 0x20, 0x36, 0xa7, 0xb0, 0xa1, 0x78, 0x88, 0x21, 0x3b, 0x90, 0x40, 0xf6, 0x0c, 0x80, + 0xe7, 0x1b, 0xae, 0xbf, 0x66, 0x1a, 0x3e, 0xe3, 0xb8, 0xdb, 0xde, 0x27, 0x8a, 0xbf, 0x55, 0x59, + 0xfc, 0xad, 0xbe, 0x22, 0x8b, 0xbf, 0xb5, 0x61, 0x2e, 0x7d, 0xcd, 0xf0, 0x19, 0xbd, 0x0c, 0x45, + 0x66, 0x9b, 0x42, 0x71, 0xb0, 0xab, 0xe2, 0x10, 0xb3, 0x4d, 0xae, 0x76, 0x15, 0x0e, 0xb6, 0xc9, + 0xb4, 0x37, 0xaa, 0xd0, 0x1d, 0xea, 0xaa, 0x3b, 0x2a, 0x15, 0xf8, 0x07, 0x28, 0x1c, 0x70, 0x5a, + 0xcc, 0x9e, 0x28, 0x9e, 0x22, 0xd3, 0xc5, 0x1a, 0xff, 0xad, 0xfd, 0x91, 0xc0, 0xe1, 0x64, 0x64, + 0xfc, 0x1f, 0x12, 0x97, 0xb4, 0x90, 0xb5, 0x3f, 0x67, 0xc8, 0x3a, 0x90, 0x16, 0xb2, 0xa6, 0xe0, + 0x10, 0xf3, 0x1a, 0xae, 0x73, 0x2f, 0x94, 0x13, 0x3e, 0x32, 0x26, 0x87, 0x31, 0x60, 0x3d, 0x85, + 0x95, 0x15, 0xbe, 0x81, 0x96, 0x5d, 0x66, 0xf8, 0x8e, 0xbb, 0xd8, 0x6c, 0x3a, 0xf7, 0x9a, 0x96, + 0x27, 0xd3, 0x7a, 0xed, 0x79, 0xac, 0x76, 0x64, 0x08, 0x85, 0x25, 0x43, 0x66, 0xb7, 0xa1, 0x0a, + 0xf7, 0x2f, 0xd6, 0xe4, 0xa3, 0x76, 0x1b, 0x4e, 0xc9, 0x63, 0xa8, 0x3d, 0x75, 0xf4, 0x33, 0x7d, + 0x3f, 0xf3, 0xde, 0x93, 0xb5, 0xa2, 0xf4, 0xc9, 0x10, 0xeb, 0x59, 0x18, 0x13, 0xfb, 0xaf, 0x81, + 0x6f, 0xb0, 0xca, 0x79, 0xb0, 0x11, 0x15, 0xef, 0xdf, 0x09, 0x77, 0x2c, 0xda, 0x1d, 0x78, 0x81, + 0x49, 0xe4, 0xda, 0x35, 0xcc, 0xee, 0xc2, 0x71, 0x04, 0x38, 0x03, 0xfb, 0xd7, 0x99, 0x0c, 0x86, + 0xc7, 0x63, 0x53, 0xca, 0xc9, 0x96, 0x1d, 0xcb, 0xae, 0xb5, 0xa5, 0xb4, 0xd3, 0x70, 0x32, 0x4a, + 0x79, 0xc9, 0xb5, 0xcc, 0x0d, 0xb6, 0x7c, 0xcb, 0xb0, 0xec, 0xe0, 0x20, 0xb8, 0x11, 0x5f, 0x82, + 0xb8, 0x48, 0x70, 0x2a, 0x1c, 0x35, 0xc4, 0xeb, 0xb5, 0x3a, 0x7f, 0xbf, 0xd6, 0xe0, 0x02, 0x68, + 0x9b, 0x23, 0x46, 0xa7, 0xae, 0xf6, 0x2a, 0xde, 0xc4, 0x30, 0x04, 0x7e, 0xd6, 0x76, 0x9d, 0x66, + 0x73, 0x93, 0xd9, 0x79, 0xaf, 0x84, 0xd1, 0x5b, 0x6b, 0x21, 0x5e, 0x69, 0x37, 0xa1, 0x9c, 0xf5, + 0x69, 0x04, 0xbc, 0x04, 0xc0, 0x82, 0x51, 0xb4, 0x95, 0x96, 0x76, 0x70, 0x84, 0xba, 0x3c, 0x85, + 0x89, 0x68, 0xb5, 0x13, 0xec, 0x8c, 0x69, 0xbc, 0xc7, 0xa0, 0xb0, 0xff, 0xe3, 0xb9, 0x78, 0xff, + 0x82, 0xe0, 0x0a, 0xa7, 0x81, 0x44, 0x63, 0x5c, 0x83, 0x91, 0x90, 0x96, 0x4c, 0x21, 0xf2, 0x58, + 0x23, 0xaa, 0xd6, 0x3f, 0x8f, 0xff, 0x0f, 0x81, 0xb1, 0xf8, 0x44, 0x8f, 0xef, 0x0a, 0x74, 0x19, + 0x06, 0x3d, 0xdf, 0xf0, 0xb7, 0x3c, 0x1e, 0xed, 0xc6, 0xe6, 0x66, 0x14, 0xf5, 0xb4, 0x70, 0xd2, + 0x97, 0xb9, 0x4a, 0x0d, 0x55, 0xe9, 0x2c, 0x8c, 0x1b, 0xad, 0x56, 0xd3, 0x6a, 0x70, 0x80, 0x6b, + 0x89, 0xc3, 0xf3, 0x48, 0xe4, 0xdd, 0xe7, 0xe5, 0x69, 0xa5, 0xc3, 0x91, 0xd0, 0x38, 0xa1, 0x86, + 0x38, 0x4e, 0x69, 0xf8, 0x4a, 0x2a, 0xcc, 0xfd, 0xfe, 0x02, 0x0c, 0xf0, 0x85, 0xa2, 0x5f, 0x23, + 0x30, 0x84, 0x4d, 0x2f, 0x3a, 0x95, 0x06, 0x37, 0xa5, 0x1b, 0x59, 0x9a, 0xee, 0x2e, 0x28, 0x4c, + 0xad, 0x3d, 0xf5, 0xf5, 0x8f, 0xfe, 0xf9, 0x5e, 0x61, 0x92, 0x3e, 0xa9, 0xa7, 0xf4, 0x3d, 0x65, + 0x93, 0xec, 0xcf, 0x04, 0xc6, 0xe2, 0x8d, 0x37, 0x5a, 0xed, 0x36, 0x43, 0xbc, 0x3a, 0x5c, 0xd2, + 0x73, 0xcb, 0x23, 0x30, 0x83, 0x03, 0xfb, 0x22, 0xbd, 0xa8, 0x00, 0x56, 0xa9, 0x6f, 0x57, 0x78, + 0x1e, 0xa4, 0xef, 0xf0, 0x3f, 0xbb, 0xab, 0x33, 0xf4, 0xbc, 0x42, 0x5e, 0x8f, 0x09, 0xd3, 0x9f, + 0x13, 0x18, 0xe0, 0xb3, 0xd3, 0xb3, 0x6a, 0x74, 0x92, 0xc4, 0xb9, 0x6e, 0x62, 0x88, 0xfd, 0x06, + 0xc7, 0x7e, 0x9d, 0x9e, 0xc9, 0xc4, 0xa2, 0xef, 0x48, 0x17, 0xdd, 0x5d, 0x9d, 0xa6, 0xe7, 0x54, + 0x98, 0x43, 0x49, 0xfa, 0x11, 0x81, 0xd1, 0x68, 0x97, 0x8d, 0x5e, 0x54, 0x03, 0x8a, 0xf7, 0x02, + 0x4b, 0x95, 0x9c, 0xd2, 0xc8, 0x62, 0x9d, 0xb3, 0xf8, 0xb2, 0x62, 0x05, 0x2a, 0xd8, 0xcb, 0x8b, + 0xb2, 0xb9, 0x44, 0xab, 0xf9, 0xd8, 0xe8, 0xb2, 0x11, 0xf8, 0x36, 0x81, 0xa2, 0xac, 0xea, 0xd3, + 0x6c, 0xcf, 0x4d, 0xb4, 0xf7, 0x4a, 0xe7, 0x73, 0x48, 0x22, 0x93, 0x33, 0x9c, 0x49, 0x99, 0x9e, + 0x48, 0x43, 0x16, 0x34, 0x01, 0xbe, 0x5b, 0x80, 0x43, 0x89, 0xfe, 0x15, 0xd5, 0xbb, 0x4e, 0x12, + 0xaf, 0x9e, 0x96, 0x2e, 0xe5, 0x57, 0x40, 0x70, 0x1f, 0x10, 0x8e, 0xee, 0x7b, 0x84, 0x5e, 0x52, + 0xc1, 0x6b, 0xfb, 0x7a, 0x87, 0xeb, 0xe8, 0xb4, 0xa2, 0xd2, 0xe9, 0xf4, 0xb5, 0x59, 0xaa, 0xe7, + 0x5c, 0x9d, 0xc0, 0x2c, 0xdf, 0x28, 0xc0, 0xd1, 0xd4, 0xf6, 0x14, 0xbd, 0x9c, 0x83, 0x6b, 0x67, + 0x7f, 0xad, 0xf4, 0x74, 0xaf, 0x6a, 0x68, 0xa8, 0x37, 0xb9, 0x9d, 0xb6, 0xe9, 0x73, 0xdd, 0xcc, + 0x14, 0x5c, 0x4f, 0x2a, 0x96, 0xa9, 0xef, 0x44, 0x2f, 0x30, 0xbb, 0xab, 0xcf, 0xd2, 0x4f, 0x29, + 0x2d, 0xa6, 0xd0, 0xa5, 0x7f, 0x25, 0x51, 0x07, 0x11, 0x71, 0x30, 0x8f, 0x83, 0xc4, 0x02, 0xe1, + 0xa5, 0xfc, 0x0a, 0xc8, 0xbb, 0xc1, 0x79, 0xdf, 0x54, 0x2f, 0x75, 0x67, 0x28, 0xbc, 0x48, 0x2f, + 0x28, 0x99, 0xc6, 0x63, 0xe1, 0x7d, 0x02, 0x43, 0x08, 0x40, 0x71, 0xcc, 0xc4, 0xcb, 0xf4, 0xa5, + 0xe9, 0xee, 0x82, 0xc8, 0xe1, 0x26, 0xe7, 0xf0, 0x05, 0x3a, 0xad, 0x80, 0xa4, 0xef, 0x84, 0xa7, + 0x7a, 0x66, 0x24, 0x0f, 0xe0, 0x47, 0x85, 0xf9, 0x21, 0x89, 0xf5, 0x71, 0x05, 0xfa, 0x78, 0x2f, + 0x4c, 0x81, 0x3e, 0xd1, 0xd4, 0x52, 0x1f, 0x92, 0xb2, 0x9e, 0xfe, 0x77, 0x02, 0x87, 0x12, 0x3d, + 0x1f, 0x85, 0x77, 0xa4, 0x77, 0xa7, 0x14, 0xde, 0x91, 0xd1, 0x4e, 0xd2, 0x18, 0xc7, 0xb6, 0x96, + 0x1e, 0x75, 0x11, 0x5b, 0xdb, 0x39, 0x44, 0xb4, 0xd5, 0x77, 0xc4, 0xdf, 0xdd, 0xd5, 0x0a, 0x9d, + 0x51, 0x68, 0xe8, 0x09, 0x71, 0xfa, 0x37, 0x02, 0x63, 0xf1, 0x0e, 0x84, 0x22, 0x05, 0x48, 0x6d, + 0x2c, 0x95, 0xf4, 0xdc, 0xf2, 0x48, 0x6d, 0x83, 0x53, 0x33, 0xd2, 0x43, 0x56, 0x84, 0x5a, 0x47, + 0x94, 0xab, 0xa6, 0x9f, 0x59, 0x92, 0x5b, 0x52, 0x9e, 0xfe, 0x5b, 0xde, 0xc2, 0x23, 0x2d, 0x20, + 0x9a, 0x63, 0x29, 0x12, 0xdb, 0x61, 0xb6, 0x07, 0x0d, 0xa4, 0xe8, 0x70, 0x8a, 0x16, 0x9d, 0xef, + 0x42, 0x31, 0x75, 0x8b, 0xcc, 0xa5, 0x9f, 0x18, 0x92, 0x66, 0x9a, 0x0e, 0xfd, 0x15, 0x81, 0x01, + 0x8e, 0x46, 0x91, 0xf3, 0x44, 0x6b, 0xee, 0x8a, 0x9c, 0x27, 0x56, 0x11, 0xd7, 0xbe, 0xc4, 0x99, + 0xdc, 0xa0, 0x53, 0x99, 0x90, 0xf4, 0x9d, 0x48, 0xed, 0x22, 0x73, 0x83, 0x4b, 0xf4, 0x31, 0x61, + 0xfa, 0x7e, 0xa1, 0xbd, 0xc1, 0x79, 0x89, 0x44, 0xb9, 0xc1, 0xa3, 0x0d, 0x20, 0xe5, 0x06, 0x8f, + 0xf5, 0x75, 0xb4, 0xdf, 0x8a, 0x33, 0xf8, 0x43, 0x92, 0xb5, 0x10, 0x5c, 0x3c, 0x8e, 0xa9, 0x1d, + 0x3a, 0x79, 0x55, 0x66, 0x77, 0xf5, 0xd3, 0xe9, 0x67, 0x52, 0x2a, 0x95, 0xf0, 0x63, 0x81, 0xfa, + 0x15, 0xfa, 0xac, 0x62, 0x56, 0x2f, 0x94, 0x4c, 0xb3, 0x23, 0xfd, 0x36, 0x81, 0xa2, 0x2c, 0xca, + 0xd3, 0xae, 0x94, 0x73, 0xa4, 0x4f, 0xc9, 0x0a, 0xbf, 0x56, 0xe5, 0xc6, 0xc9, 0x48, 0x53, 0x3b, + 0x51, 0xd2, 0x7f, 0xf1, 0x48, 0x18, 0x6b, 0x9c, 0x28, 0x23, 0x61, 0x5a, 0xaf, 0x47, 0x19, 0x09, + 0x53, 0x7b, 0x32, 0xda, 0x1d, 0x0e, 0xf3, 0x75, 0xe5, 0x12, 0xf2, 0xcd, 0x94, 0xe6, 0x8d, 0x0b, + 0x74, 0xae, 0xe7, 0x25, 0xf4, 0xe8, 0x87, 0x04, 0x46, 0x22, 0x3d, 0x11, 0x3a, 0x93, 0x09, 0xba, + 0xb3, 0x3b, 0x53, 0xba, 0x98, 0x4f, 0x18, 0xd9, 0x7d, 0x8e, 0xb3, 0x5b, 0xa2, 0xa7, 0xd2, 0x60, + 0x1a, 0xcd, 0x66, 0x45, 0x82, 0x5a, 0xcd, 0xc8, 0x73, 0x03, 0xd0, 0xbf, 0x23, 0x30, 0x28, 0x3a, + 0x1d, 0x34, 0x7b, 0x73, 0xc7, 0x5a, 0x28, 0xa5, 0xa9, 0xae, 0x72, 0x88, 0xd2, 0xe4, 0x28, 0x5f, + 0x4b, 0x3f, 0xe7, 0x3d, 0x2e, 0x9b, 0x30, 0x7c, 0x97, 0x20, 0x16, 0x37, 0xbc, 0xf8, 0x02, 0xfd, + 0x0e, 0x81, 0x91, 0x48, 0xfb, 0x43, 0x61, 0xf6, 0xce, 0xfe, 0x89, 0xc2, 0xec, 0x29, 0x1d, 0x15, + 0x6d, 0x9a, 0x13, 0xd2, 0xd2, 0xcd, 0x2e, 0x7e, 0x55, 0x78, 0xaf, 0x85, 0xbe, 0x45, 0x60, 0x50, + 0xb4, 0x3a, 0x14, 0x66, 0x8d, 0x75, 0x55, 0x14, 0x66, 0x8d, 0xf7, 0x59, 0xb4, 0xb3, 0x1c, 0xc5, + 0x09, 0x5a, 0x4a, 0x4d, 0x89, 0xb8, 0xec, 0x37, 0x0b, 0x84, 0x3e, 0x20, 0x00, 0x21, 0x09, 0x7a, + 0x21, 0x07, 0x53, 0x09, 0x65, 0x26, 0x97, 0x2c, 0xc2, 0xb1, 0x38, 0x9c, 0x46, 0xc6, 0x4d, 0x2f, + 0x34, 0x8a, 0xbe, 0x13, 0xed, 0xdd, 0x64, 0xdf, 0x3e, 0x22, 0x66, 0x4c, 0xa8, 0xb4, 0xf3, 0xd2, + 0xa3, 0xa9, 0xe5, 0x62, 0xc5, 0xed, 0x43, 0x55, 0x83, 0x56, 0xdc, 0x3e, 0x94, 0x55, 0x69, 0x6d, + 0x9e, 0x73, 0xce, 0xc8, 0x9a, 0xc4, 0x6d, 0x18, 0x6b, 0xc0, 0x15, 0x23, 0xc0, 0xf8, 0x1b, 0x02, + 0xe3, 0x69, 0xf5, 0x63, 0xba, 0xa0, 0xda, 0xfb, 0x59, 0xb5, 0xed, 0xd2, 0xe5, 0x1e, 0xb5, 0x10, + 0xfa, 0x1c, 0x87, 0x9e, 0x71, 0x1f, 0xc0, 0x62, 0x6c, 0x25, 0x46, 0xc1, 0xa3, 0xef, 0x10, 0x28, + 0xca, 0x62, 0x32, 0xed, 0x52, 0x4e, 0x0a, 0xeb, 0xd0, 0x8a, 0x53, 0x25, 0x59, 0x99, 0x46, 0x9f, + 0x3e, 0x49, 0x27, 0xb3, 0x0d, 0xba, 0xce, 0x18, 0xfd, 0x25, 0x81, 0x23, 0x29, 0xc5, 0x66, 0x3a, + 0xdf, 0xcd, 0x16, 0x29, 0xd5, 0xeb, 0xd2, 0x42, 0x6f, 0x4a, 0x88, 0x74, 0x96, 0x23, 0xcd, 0xc8, + 0x57, 0xa4, 0xfd, 0x44, 0xa5, 0xbb, 0x22, 0x2a, 0xdd, 0xf4, 0x0f, 0x04, 0x9e, 0xe8, 0xa8, 0x23, + 0xd2, 0xd9, 0x6e, 0xf7, 0xa5, 0x8e, 0xb2, 0x77, 0x69, 0xae, 0x17, 0x15, 0xc4, 0xfb, 0x22, 0xc7, + 0xbb, 0x48, 0xaf, 0xe6, 0xbd, 0x6c, 0xe9, 0x91, 0xca, 0x6d, 0x34, 0x2f, 0xbe, 0x4f, 0x80, 0x76, + 0x56, 0x8a, 0x69, 0x0f, 0x98, 0x02, 0xcb, 0xcf, 0xf7, 0xa4, 0x83, 0x44, 0xae, 0x70, 0x22, 0x4f, + 0xd3, 0x85, 0xc7, 0x21, 0xb2, 0xf4, 0xea, 0x9f, 0x1e, 0x96, 0xc9, 0x83, 0x87, 0x65, 0xf2, 0x8f, + 0x87, 0x65, 0xf2, 0xee, 0xa3, 0xf2, 0xbe, 0x07, 0x8f, 0xca, 0xfb, 0xfe, 0xf2, 0xa8, 0xbc, 0x6f, + 0xf5, 0xea, 0x86, 0xe5, 0xdf, 0xda, 0xaa, 0x57, 0x1b, 0xce, 0xa6, 0xf8, 0x72, 0xc5, 0x66, 0xfe, + 0x3d, 0xc7, 0x7d, 0x1d, 0x9f, 0x9a, 0xcc, 0xdc, 0x60, 0xae, 0xfe, 0x46, 0x64, 0x42, 0xfe, 0xdf, + 0x28, 0x22, 0x42, 0xdd, 0x9d, 0xad, 0x0f, 0xf2, 0x66, 0xdf, 0xfc, 0x7f, 0x03, 0x00, 0x00, 0xff, + 0xff, 0xb3, 0x37, 0xda, 0x06, 0x0c, 0x33, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3580,8 +3681,8 @@ type QueryClient interface { // // Since Revision 3 ProjectEnrollment(ctx context.Context, in *QueryProjectEnrollmentRequest, opts ...grpc.CallOption) (*QueryProjectEnrollmentResponse, error) - // ProjectEnrollments queries all credit class enrollments associated with a - // project. + // ProjectEnrollments queries all credit class enrollments and allows for filtering by + // project or credit class. ProjectEnrollments(ctx context.Context, in *QueryProjectEnrollmentsRequest, opts ...grpc.CallOption) (*QueryProjectEnrollmentsResponse, error) } @@ -3929,8 +4030,8 @@ type QueryServer interface { // // Since Revision 3 ProjectEnrollment(context.Context, *QueryProjectEnrollmentRequest) (*QueryProjectEnrollmentResponse, error) - // ProjectEnrollments queries all credit class enrollments associated with a - // project. + // ProjectEnrollments queries all credit class enrollments and allows for filtering by + // project or credit class. ProjectEnrollments(context.Context, *QueryProjectEnrollmentsRequest) (*QueryProjectEnrollmentsResponse, error) } @@ -6993,9 +7094,9 @@ func (m *QueryProjectEnrollmentResponse) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l - if m.ProjectClass != nil { + if m.Enrollment != nil { { - size, err := m.ProjectClass.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Enrollment.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -7028,6 +7129,13 @@ func (m *QueryProjectEnrollmentsRequest) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if len(m.ClassId) > 0 { + i -= len(m.ClassId) + copy(dAtA[i:], m.ClassId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ClassId))) + i-- + dAtA[i] = 0x1a + } if m.Pagination != nil { { size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) @@ -7099,6 +7207,62 @@ func (m *QueryProjectEnrollmentsResponse) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *EnrollmentInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EnrollmentInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EnrollmentInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.EnrollmentMetadata) > 0 { + i -= len(m.EnrollmentMetadata) + copy(dAtA[i:], m.EnrollmentMetadata) + i = encodeVarintQuery(dAtA, i, uint64(len(m.EnrollmentMetadata))) + i-- + dAtA[i] = 0x32 + } + if len(m.ApplicationMetadata) > 0 { + i -= len(m.ApplicationMetadata) + copy(dAtA[i:], m.ApplicationMetadata) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ApplicationMetadata))) + i-- + dAtA[i] = 0x2a + } + if m.Status != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x20 + } + if len(m.ClassId) > 0 { + i -= len(m.ClassId) + copy(dAtA[i:], m.ClassId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ClassId))) + i-- + dAtA[i] = 0x12 + } + if len(m.ProjectId) > 0 { + i -= len(m.ProjectId) + copy(dAtA[i:], m.ProjectId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProjectId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -8061,8 +8225,8 @@ func (m *QueryProjectEnrollmentResponse) Size() (n int) { } var l int _ = l - if m.ProjectClass != nil { - l = m.ProjectClass.Size() + if m.Enrollment != nil { + l = m.Enrollment.Size() n += 1 + l + sovQuery(uint64(l)) } return n @@ -8082,6 +8246,10 @@ func (m *QueryProjectEnrollmentsRequest) Size() (n int) { l = m.Pagination.Size() n += 1 + l + sovQuery(uint64(l)) } + l = len(m.ClassId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } return n } @@ -8104,6 +8272,34 @@ func (m *QueryProjectEnrollmentsResponse) Size() (n int) { return n } +func (m *EnrollmentInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProjectId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ClassId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Status != 0 { + n += 1 + sovQuery(uint64(m.Status)) + } + l = len(m.ApplicationMetadata) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.EnrollmentMetadata) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -14355,7 +14551,7 @@ func (m *QueryProjectEnrollmentResponse) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProjectClass", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Enrollment", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14382,10 +14578,10 @@ func (m *QueryProjectEnrollmentResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ProjectClass == nil { - m.ProjectClass = &ProjectEnrollment{} + if m.Enrollment == nil { + m.Enrollment = &EnrollmentInfo{} } - if err := m.ProjectClass.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Enrollment.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14507,6 +14703,38 @@ func (m *QueryProjectEnrollmentsRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClassId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClassId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -14586,7 +14814,7 @@ func (m *QueryProjectEnrollmentsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Enrollments = append(m.Enrollments, &ProjectEnrollment{}) + m.Enrollments = append(m.Enrollments, &EnrollmentInfo{}) if err := m.Enrollments[len(m.Enrollments)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -14648,6 +14876,203 @@ func (m *QueryProjectEnrollmentsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *EnrollmentInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EnrollmentInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EnrollmentInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProjectId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClassId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClassId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= ProjectEnrollmentStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApplicationMetadata", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ApplicationMetadata = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EnrollmentMetadata", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EnrollmentMetadata = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ecocredit/base/types/v1/state.pb.go b/x/ecocredit/base/types/v1/state.pb.go index 7c6f1bd9c5..174f04a262 100644 --- a/x/ecocredit/base/types/v1/state.pb.go +++ b/x/ecocredit/base/types/v1/state.pb.go @@ -81,6 +81,8 @@ func (ProjectEnrollmentStatus) EnumDescriptor() ([]byte, []int) { type CreditType struct { // abbreviation is a 1-3 character uppercase abbreviation of the CreditType // name, used in batch denominations within the CreditType. It must be unique. + // The letter P is reserved as the project prefix and cannot be used as a + // credit type to avoid confusion. Abbreviation string `protobuf:"bytes,1,opt,name=abbreviation,proto3" json:"abbreviation,omitempty"` // name is the name of the credit type (e.g. carbon, biodiversity). Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` @@ -297,14 +299,12 @@ type Project struct { // key is the table row identifier of the project used internally for // efficient lookups. This identifier is auto-incrementing. Key uint64 `protobuf:"varint,1,opt,name=key,proto3" json:"key,omitempty"` - // id is the unique identifier of the project either auto-generated from the - // credit class id and project sequence number or provided upon creation. + // id is the auto-generated unique identifier of the project. Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` // admin is the admin of the project. Admin []byte `protobuf:"bytes,3,opt,name=admin,proto3" json:"admin,omitempty"` - // class_key is the table row identifier of the credit class used internally - // for efficient lookups. This links a project to a credit class. - ClassKey uint64 `protobuf:"varint,4,opt,name=class_key,json=classKey,proto3" json:"class_key,omitempty"` + // Deprecated: use ProjectEnrollment instead. + ClassKey uint64 `protobuf:"varint,4,opt,name=class_key,json=classKey,proto3" json:"class_key,omitempty"` // Deprecated: Do not use. // jurisdiction is the jurisdiction of the project. // Full documentation can be found in MsgCreateProject.jurisdiction. Jurisdiction string `protobuf:"bytes,5,opt,name=jurisdiction,proto3" json:"jurisdiction,omitempty"` @@ -368,6 +368,7 @@ func (m *Project) GetAdmin() []byte { return nil } +// Deprecated: Do not use. func (m *Project) GetClassKey() uint64 { if m != nil { return m.ClassKey @@ -591,8 +592,9 @@ func (m *ClassSequence) GetNextSequence() uint64 { return 0 } -// ProjectSequence stores and increments the sequence number for projects within -// a credit class. +// Deprecated: No longer used. +// +// Deprecated: Do not use. type ProjectSequence struct { // class_key is the table row identifier of the credit class used internally // for efficient lookups. This links a project sequence to a credit class. @@ -1385,96 +1387,96 @@ func init() { func init() { proto.RegisterFile("regen/ecocredit/v1/state.proto", fileDescriptor_6cfdca0a4aaabb36) } var fileDescriptor_6cfdca0a4aaabb36 = []byte{ - // 1413 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcd, 0x72, 0xdb, 0xd4, - 0x17, 0x8f, 0xfc, 0x91, 0xd8, 0xc7, 0x1f, 0x51, 0x6e, 0xbe, 0xd4, 0xfc, 0xfb, 0x77, 0x8b, 0x68, - 0x69, 0xda, 0x06, 0x9b, 0x14, 0x98, 0x01, 0x33, 0x43, 0xc7, 0x71, 0x5c, 0x08, 0x6d, 0xd3, 0xa0, - 0xb8, 0x0b, 0xba, 0x11, 0xd7, 0xd2, 0x6d, 0xa2, 0x56, 0x96, 0x8c, 0x74, 0x9d, 0x26, 0x5b, 0x1e, - 0x80, 0x61, 0xc5, 0x8a, 0xe1, 0x05, 0xe0, 0x11, 0x58, 0xb2, 0x80, 0x5d, 0x67, 0xd8, 0xb0, 0x64, - 0xda, 0x07, 0x60, 0x86, 0x61, 0xc5, 0x8a, 0xb9, 0x47, 0x57, 0xb2, 0xe5, 0x3a, 0x69, 0xa7, 0x3b, - 0x9d, 0xef, 0xdf, 0xf9, 0xdd, 0x73, 0xa4, 0x2b, 0xa8, 0x05, 0xec, 0x80, 0x79, 0x0d, 0x66, 0xf9, - 0x56, 0xc0, 0x6c, 0x87, 0x37, 0x8e, 0x36, 0x1b, 0x21, 0xa7, 0x9c, 0xd5, 0x07, 0x81, 0xcf, 0x7d, - 0x42, 0xd0, 0x5e, 0x4f, 0xec, 0xf5, 0xa3, 0xcd, 0xb5, 0x9a, 0xe5, 0x87, 0x7d, 0x3f, 0x6c, 0xf4, - 0x68, 0xc8, 0x1a, 0x47, 0x9b, 0x3d, 0xc6, 0xe9, 0x66, 0xc3, 0xf2, 0x1d, 0x2f, 0x8a, 0x59, 0x5b, - 0x95, 0x76, 0x3f, 0xe8, 0x8b, 0x74, 0x7e, 0xd0, 0x97, 0x86, 0x0b, 0x07, 0xbe, 0x7f, 0xe0, 0xb2, - 0x06, 0x4a, 0xbd, 0xe1, 0xc3, 0x06, 0x77, 0xfa, 0x2c, 0xe4, 0xb4, 0x3f, 0x88, 0x1c, 0xf4, 0xef, - 0x15, 0x80, 0x36, 0xd6, 0xe9, 0x9e, 0x0c, 0x18, 0xd1, 0xa1, 0x4c, 0x7b, 0xbd, 0x80, 0x1d, 0x39, - 0x94, 0x3b, 0xbe, 0xa7, 0x29, 0x17, 0x95, 0xf5, 0xa2, 0x91, 0xd2, 0x11, 0x02, 0x39, 0x8f, 0xf6, - 0x99, 0x96, 0x41, 0x1b, 0x3e, 0x0b, 0xdd, 0xd0, 0x73, 0xb8, 0x96, 0x8d, 0x74, 0xe2, 0x99, 0x9c, - 0x87, 0xe2, 0x20, 0x60, 0x96, 0x13, 0x8a, 0x44, 0xb9, 0x8b, 0xca, 0x7a, 0xc5, 0x18, 0x29, 0x9a, - 0x97, 0xfe, 0xfe, 0xe1, 0xf7, 0x6f, 0xb2, 0x35, 0xa8, 0xa6, 0x2b, 0x12, 0x88, 0xb2, 0xab, 0x8a, - 0xa6, 0x68, 0x8a, 0xfe, 0x9b, 0x02, 0xf9, 0xb6, 0x4b, 0xc3, 0x90, 0xa8, 0x90, 0x7d, 0xcc, 0x4e, - 0x10, 0x50, 0xce, 0x10, 0x8f, 0xa4, 0x0a, 0x19, 0xc7, 0x96, 0x28, 0x32, 0x8e, 0x4d, 0x96, 0x20, - 0x4f, 0xed, 0xbe, 0xe3, 0x21, 0x88, 0xb2, 0x11, 0x09, 0x64, 0x0d, 0x0a, 0x7d, 0xc6, 0xa9, 0x4d, - 0x39, 0x45, 0x10, 0x45, 0x23, 0x91, 0xc9, 0x06, 0x90, 0x88, 0x63, 0x93, 0x9f, 0x0c, 0x98, 0x19, - 0xe1, 0xd0, 0xf2, 0xe8, 0xa5, 0x5a, 0x09, 0x2b, 0x2d, 0xd4, 0x37, 0x3f, 0x46, 0xc4, 0x1f, 0xc0, - 0x1c, 0x22, 0x51, 0x15, 0x52, 0x10, 0x00, 0x04, 0x50, 0x52, 0x94, 0xa5, 0xd5, 0x0c, 0x59, 0x99, - 0x96, 0x53, 0xcd, 0x6a, 0x19, 0xfd, 0x4b, 0x28, 0x61, 0x2b, 0x3b, 0x61, 0x38, 0x64, 0x01, 0xf9, - 0x1f, 0x14, 0x2d, 0x21, 0x9a, 0xa3, 0xb6, 0x0a, 0xa8, 0xb8, 0xcd, 0x4e, 0xc8, 0x0a, 0xcc, 0x3a, - 0xe8, 0x86, 0xfd, 0x95, 0x0d, 0x29, 0x35, 0xcf, 0x23, 0x86, 0x15, 0x20, 0xa0, 0x26, 0xc1, 0x1b, - 0xd2, 0x33, 0xab, 0xff, 0x98, 0x81, 0xb9, 0xbd, 0xc0, 0x7f, 0xc4, 0x2c, 0xfe, 0xda, 0x7c, 0xa5, - 0x60, 0xe5, 0x26, 0x60, 0xe9, 0x50, 0x7e, 0x34, 0x0c, 0x9c, 0xd0, 0x76, 0x2c, 0x1c, 0x8f, 0x88, - 0xaa, 0x94, 0x2e, 0x45, 0xf8, 0xec, 0x04, 0xe1, 0x6f, 0x40, 0x39, 0x60, 0x0f, 0x59, 0xc0, 0x3c, - 0x8b, 0x99, 0x8e, 0xad, 0xcd, 0xa1, 0xbd, 0x94, 0xe8, 0x76, 0xec, 0xe6, 0x21, 0x76, 0xd8, 0x9b, - 0xc6, 0x32, 0x81, 0xf2, 0x58, 0xd3, 0xb6, 0x9a, 0x19, 0x67, 0x3e, 0x4b, 0xd4, 0x74, 0x72, 0x35, - 0x47, 0xd6, 0x60, 0x65, 0x14, 0x90, 0xb2, 0xe5, 0xb5, 0x9c, 0xfe, 0x4b, 0x16, 0xf2, 0x5b, 0x94, - 0x5b, 0x87, 0x53, 0xb8, 0x3a, 0x85, 0x7f, 0x72, 0x01, 0x4a, 0x83, 0x88, 0x60, 0xe4, 0x27, 0x8b, - 0x11, 0x20, 0x55, 0x82, 0xa1, 0x25, 0xc8, 0xdb, 0xcc, 0xf3, 0xfb, 0x72, 0xd6, 0x22, 0x21, 0xc5, - 0x49, 0x7e, 0x82, 0x93, 0x0f, 0x01, 0x42, 0x4e, 0x03, 0x6e, 0xda, 0x94, 0x33, 0x64, 0xac, 0x74, - 0x63, 0xad, 0x1e, 0xed, 0x6d, 0x3d, 0xde, 0xdb, 0x7a, 0x37, 0xde, 0x5b, 0xa3, 0x88, 0xde, 0xdb, - 0x94, 0x33, 0xf2, 0x3e, 0x14, 0x98, 0x67, 0x47, 0x81, 0x73, 0x2f, 0x0d, 0x9c, 0x63, 0x9e, 0x8d, - 0x61, 0x37, 0xa1, 0x22, 0xda, 0xa1, 0x82, 0x0b, 0x8c, 0x2d, 0xbc, 0x34, 0xb6, 0x1c, 0x07, 0x60, - 0x02, 0x02, 0x39, 0x7f, 0xc0, 0x3c, 0xad, 0x78, 0x51, 0x59, 0x2f, 0x18, 0xf8, 0x9c, 0x9e, 0x1b, - 0x48, 0xcf, 0x4d, 0xf3, 0x01, 0x1e, 0x6a, 0x77, 0x74, 0xa8, 0x25, 0x49, 0x13, 0x9e, 0xeb, 0x7c, - 0x8a, 0x54, 0x35, 0x43, 0xaa, 0xe3, 0x94, 0xa8, 0x59, 0x02, 0xf1, 0x69, 0xa8, 0x39, 0x52, 0x19, - 0xab, 0xa3, 0xe6, 0xb5, 0xbc, 0xfe, 0xb5, 0x02, 0x15, 0xdc, 0xab, 0x7d, 0xf6, 0xd5, 0x50, 0x9c, - 0xef, 0x29, 0x6b, 0xad, 0x4c, 0x5f, 0x6b, 0xf2, 0x26, 0x54, 0x3c, 0x76, 0xcc, 0xcd, 0x50, 0x86, - 0xe3, 0x89, 0xe7, 0x8c, 0xb2, 0x50, 0xc6, 0x29, 0x9b, 0x35, 0x6c, 0x40, 0x83, 0xa5, 0xa9, 0xa9, - 0x67, 0xf5, 0x47, 0x30, 0x2f, 0x17, 0x2f, 0x41, 0x71, 0xe6, 0x7e, 0xbf, 0x52, 0xd1, 0x65, 0x2c, - 0x3a, 0x0f, 0xa5, 0xf1, 0x4c, 0x73, 0xba, 0x07, 0x15, 0x1c, 0xdb, 0xa4, 0xd2, 0xc4, 0x50, 0x2a, - 0x2f, 0x0c, 0xe5, 0x2b, 0x55, 0x5b, 0xc5, 0x6a, 0x0b, 0x50, 0x49, 0x67, 0x2b, 0xe8, 0xff, 0x28, - 0x50, 0xc6, 0x82, 0x5b, 0xd4, 0xa5, 0xb2, 0xb3, 0x9e, 0x90, 0xc7, 0x3b, 0x43, 0x85, 0xa8, 0xa5, - 0xc1, 0x1c, 0xb5, 0xed, 0x80, 0x85, 0xa1, 0x5c, 0x9d, 0x58, 0x24, 0x57, 0x60, 0x9e, 0x07, 0xd4, - 0xa6, 0x3d, 0x97, 0x99, 0xb4, 0xef, 0x0f, 0xbd, 0xf8, 0x73, 0x51, 0x8d, 0xd5, 0x2d, 0xd4, 0x92, - 0xcb, 0x50, 0x0d, 0x18, 0x77, 0x02, 0x66, 0xc7, 0x7e, 0xd1, 0x32, 0x55, 0xa4, 0x56, 0xba, 0x5d, - 0x81, 0x79, 0x16, 0x5a, 0x81, 0xff, 0x64, 0xe4, 0x17, 0xed, 0x56, 0x35, 0x56, 0x47, 0x8e, 0xcd, - 0xf7, 0xb0, 0xb3, 0x3a, 0x2c, 0xc2, 0x82, 0xc4, 0xb2, 0x91, 0xe0, 0x27, 0xcb, 0xb0, 0x90, 0x08, - 0x1b, 0xd2, 0xac, 0x2a, 0x5a, 0x51, 0xff, 0x59, 0x81, 0x52, 0xc4, 0xf3, 0x70, 0x30, 0x70, 0x4f, - 0xce, 0xee, 0x7a, 0x4a, 0x6f, 0x99, 0x57, 0xec, 0x2d, 0x3b, 0xad, 0xb7, 0xab, 0xa0, 0x5a, 0x82, - 0x6b, 0xd7, 0x9d, 0x24, 0x61, 0x3e, 0xd1, 0xcb, 0xee, 0xc6, 0xa6, 0x64, 0x84, 0x0f, 0xf4, 0x21, - 0x54, 0xee, 0x05, 0xce, 0x81, 0xe3, 0x75, 0x8f, 0x77, 0x3c, 0x9b, 0x1d, 0x9f, 0x3d, 0x8f, 0x93, - 0xdf, 0x86, 0x15, 0x98, 0x0d, 0xfd, 0x61, 0x60, 0x31, 0x09, 0x4f, 0x4a, 0xcd, 0x0b, 0x58, 0xec, - 0x1c, 0x2c, 0xc3, 0xe2, 0xf8, 0xab, 0x78, 0x43, 0x3a, 0x97, 0xf4, 0xef, 0x14, 0x39, 0x9d, 0x6d, - 0xdf, 0xe3, 0x01, 0xb5, 0xf8, 0xd9, 0xbc, 0xa5, 0x40, 0x65, 0x26, 0x40, 0xad, 0x41, 0xc1, 0x92, - 0x59, 0x24, 0x8c, 0x44, 0x6e, 0x36, 0x10, 0xc8, 0xd5, 0x54, 0xd7, 0x44, 0x03, 0x32, 0x42, 0x15, - 0xbb, 0xe2, 0x4d, 0xa2, 0xac, 0x7f, 0x04, 0xcb, 0xf8, 0x96, 0x68, 0x07, 0x8c, 0x72, 0x3f, 0x68, - 0xb9, 0xae, 0xff, 0xc4, 0x75, 0x42, 0x2e, 0x06, 0x96, 0x79, 0xe2, 0x84, 0x6c, 0x44, 0x57, 0x30, - 0x62, 0xb1, 0x59, 0xf8, 0x57, 0xd4, 0xc8, 0x14, 0x2a, 0xfa, 0x36, 0x2c, 0x62, 0x00, 0xb3, 0xc7, - 0x73, 0x8c, 0xcf, 0xba, 0x92, 0x9a, 0xf5, 0xe6, 0x22, 0xc2, 0xab, 0x40, 0x71, 0xe4, 0x51, 0xd5, - 0x5b, 0x50, 0xc0, 0xf0, 0x5b, 0x8c, 0x91, 0xeb, 0x90, 0x7d, 0xc8, 0x18, 0x86, 0x95, 0x6e, 0x9c, - 0xab, 0x47, 0xf7, 0xb7, 0xba, 0xb8, 0xdf, 0xd5, 0xe5, 0xfd, 0xae, 0xde, 0xf6, 0x1d, 0xcf, 0x10, - 0x5e, 0x09, 0x90, 0x79, 0xfd, 0x36, 0x10, 0x09, 0x64, 0x2b, 0x70, 0xec, 0x03, 0xd6, 0x3e, 0xa4, - 0x8e, 0x47, 0xfe, 0x0f, 0x60, 0x89, 0x07, 0x13, 0xef, 0x65, 0xd1, 0x8b, 0xae, 0x88, 0x9a, 0x5d, - 0xda, 0x67, 0xcd, 0x15, 0x04, 0xa3, 0x42, 0x39, 0xe5, 0xa6, 0xea, 0x3f, 0x65, 0x60, 0x41, 0xbe, - 0xb5, 0x3a, 0x5e, 0xe0, 0xbb, 0x6e, 0x9f, 0x79, 0xfc, 0xe5, 0x6f, 0x93, 0xd4, 0x99, 0x65, 0x27, - 0xce, 0xac, 0x0d, 0xb3, 0xe2, 0x32, 0x3b, 0x0c, 0x71, 0x5c, 0xab, 0x37, 0xae, 0xd7, 0x5f, 0xbc, - 0xce, 0xd6, 0x5f, 0x28, 0xba, 0x8f, 0x21, 0x86, 0x0c, 0x25, 0x9b, 0xb0, 0x44, 0x07, 0x03, 0xd7, - 0xb1, 0xf0, 0x4a, 0x68, 0x4e, 0x7c, 0x3a, 0x17, 0xc7, 0x6c, 0x77, 0xe3, 0xaf, 0x68, 0x03, 0x16, - 0x59, 0x92, 0xce, 0x9c, 0xb8, 0x80, 0x90, 0x91, 0x29, 0x0e, 0x68, 0xbe, 0x83, 0xa4, 0x5c, 0x83, - 0x55, 0x58, 0x1e, 0x6b, 0x77, 0x23, 0xe9, 0x2c, 0xfd, 0xa1, 0x51, 0xb4, 0x05, 0xbd, 0x0d, 0x20, - 0x81, 0xbf, 0xf6, 0x01, 0x92, 0x6b, 0x7f, 0x29, 0xb0, 0x7a, 0x4a, 0xfb, 0xe4, 0x2a, 0x5c, 0xde, - 0x33, 0xee, 0x7d, 0xd6, 0x69, 0x77, 0xcd, 0xce, 0xae, 0x71, 0xef, 0xce, 0x9d, 0xbb, 0x9d, 0xdd, - 0xae, 0xb9, 0xdf, 0x6d, 0x75, 0xef, 0xef, 0x9b, 0xf7, 0x77, 0xf7, 0xf7, 0x3a, 0xed, 0x9d, 0x5b, - 0x3b, 0x9d, 0x6d, 0x75, 0x86, 0xbc, 0x05, 0xfa, 0xe9, 0xae, 0xad, 0x76, 0xbb, 0xb3, 0xd7, 0xed, - 0x6c, 0xab, 0x0a, 0x69, 0xc0, 0xf5, 0xd3, 0xfd, 0xda, 0x9f, 0xb6, 0x76, 0x3f, 0xe9, 0xec, 0x9b, - 0x46, 0xe7, 0xf3, 0xfb, 0x9d, 0x7d, 0x11, 0x90, 0x39, 0x3b, 0xb1, 0xd1, 0x11, 0x86, 0xce, 0xb6, - 0x9a, 0x25, 0xeb, 0x70, 0xe9, 0x74, 0xbf, 0x6e, 0xc7, 0xb8, 0xbb, 0xb3, 0xdb, 0x12, 0x9e, 0xb9, - 0xad, 0x2f, 0x7e, 0x7d, 0x56, 0x53, 0x9e, 0x3e, 0xab, 0x29, 0x7f, 0x3e, 0xab, 0x29, 0xdf, 0x3e, - 0xaf, 0xcd, 0x3c, 0x7d, 0x5e, 0x9b, 0xf9, 0xe3, 0x79, 0x6d, 0xe6, 0xc1, 0xcd, 0x03, 0x87, 0x1f, - 0x0e, 0x7b, 0x75, 0xcb, 0xef, 0x37, 0x70, 0x4a, 0xde, 0xf6, 0x18, 0x7f, 0xe2, 0x07, 0x8f, 0xa5, - 0xe4, 0x32, 0xfb, 0x80, 0x05, 0x8d, 0xe3, 0xb1, 0x7f, 0x25, 0xfc, 0x01, 0x12, 0x9f, 0xde, 0x50, - 0xfc, 0x06, 0xcd, 0xe2, 0x4d, 0xe5, 0xdd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x14, 0xb3, - 0xd1, 0x53, 0x0d, 0x00, 0x00, + // 1420 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcd, 0x72, 0xdb, 0x54, + 0x14, 0x8e, 0xfc, 0x93, 0xd8, 0xc7, 0x3f, 0x51, 0x6e, 0xfe, 0xd4, 0x50, 0x9c, 0x22, 0x5a, 0x9a, + 0xb6, 0xc1, 0x26, 0x05, 0x66, 0xc0, 0xcc, 0xd0, 0x71, 0x1c, 0x17, 0x42, 0xdb, 0x34, 0x28, 0xee, + 0x82, 0x6e, 0xcc, 0xb5, 0x74, 0x9b, 0xa8, 0x95, 0x25, 0x23, 0x5d, 0xa7, 0xc9, 0x96, 0x07, 0x60, + 0x58, 0xb1, 0x62, 0x78, 0x02, 0x66, 0x78, 0x01, 0x96, 0x2c, 0x60, 0xd7, 0x19, 0x36, 0x2c, 0x99, + 0xf6, 0x01, 0x98, 0x61, 0x58, 0xb1, 0x62, 0xee, 0xd1, 0x95, 0x2c, 0xb9, 0x49, 0x5a, 0xba, 0xd3, + 0x39, 0xf7, 0xfc, 0x7c, 0xe7, 0x3b, 0xe7, 0x48, 0x57, 0x50, 0xf3, 0xd9, 0x3e, 0x73, 0x1b, 0xcc, + 0xf4, 0x4c, 0x9f, 0x59, 0x36, 0x6f, 0x1c, 0x6e, 0x34, 0x02, 0x4e, 0x39, 0xab, 0x0f, 0x7d, 0x8f, + 0x7b, 0x84, 0xe0, 0x79, 0x3d, 0x3e, 0xaf, 0x1f, 0x6e, 0xac, 0xd4, 0x4c, 0x2f, 0x18, 0x78, 0x41, + 0xa3, 0x4f, 0x03, 0xd6, 0x38, 0xdc, 0xe8, 0x33, 0x4e, 0x37, 0x1a, 0xa6, 0x67, 0xbb, 0xa1, 0xcf, + 0xca, 0xb2, 0x3c, 0xf7, 0xfc, 0x81, 0x08, 0xe7, 0xf9, 0x03, 0x79, 0xb0, 0xba, 0xef, 0x79, 0xfb, + 0x0e, 0x6b, 0xa0, 0xd4, 0x1f, 0x3d, 0x68, 0x70, 0x7b, 0xc0, 0x02, 0x4e, 0x07, 0xc3, 0xd0, 0x40, + 0xff, 0x5e, 0x01, 0x68, 0x63, 0x9e, 0xee, 0xf1, 0x90, 0x11, 0x1d, 0xca, 0xb4, 0xdf, 0xf7, 0xd9, + 0xa1, 0x4d, 0xb9, 0xed, 0xb9, 0x9a, 0x72, 0x41, 0x59, 0x2b, 0x1a, 0x29, 0x1d, 0x21, 0x90, 0x73, + 0xe9, 0x80, 0x69, 0x19, 0x3c, 0xc3, 0x67, 0xa1, 0x1b, 0xb9, 0x36, 0xd7, 0xb2, 0xa1, 0x4e, 0x3c, + 0x93, 0xf3, 0x50, 0x1c, 0xfa, 0xcc, 0xb4, 0x03, 0x11, 0x28, 0x77, 0x41, 0x59, 0xab, 0x18, 0x63, + 0x45, 0xf3, 0xe2, 0xdf, 0x3f, 0xfc, 0xfe, 0x4d, 0xb6, 0x06, 0xd5, 0x74, 0x46, 0x02, 0x61, 0x74, + 0x55, 0xd1, 0x14, 0x4d, 0xd1, 0x7f, 0x53, 0x20, 0xdf, 0x76, 0x68, 0x10, 0x10, 0x15, 0xb2, 0x8f, + 0xd8, 0x31, 0x02, 0xca, 0x19, 0xe2, 0x91, 0x54, 0x21, 0x63, 0x5b, 0x12, 0x45, 0xc6, 0xb6, 0xc8, + 0x02, 0xe4, 0xa9, 0x35, 0xb0, 0x5d, 0x04, 0x51, 0x36, 0x42, 0x81, 0xac, 0x40, 0x61, 0xc0, 0x38, + 0xb5, 0x28, 0xa7, 0x08, 0xa2, 0x68, 0xc4, 0x32, 0x59, 0x07, 0x12, 0x72, 0xdc, 0xe3, 0xc7, 0x43, + 0xd6, 0x0b, 0x71, 0x68, 0x79, 0xb4, 0x52, 0xcd, 0x98, 0x95, 0x16, 0xea, 0x9b, 0x1f, 0x23, 0xe2, + 0x0f, 0x60, 0x06, 0x91, 0xa8, 0x0a, 0x29, 0x08, 0x00, 0x02, 0x28, 0x29, 0xca, 0xd4, 0x6a, 0x86, + 0x2c, 0x9d, 0x14, 0x53, 0xcd, 0x6a, 0x19, 0xfd, 0x4b, 0x28, 0x61, 0x29, 0xdb, 0x41, 0x30, 0x62, + 0x3e, 0x79, 0x0d, 0x8a, 0xa6, 0x10, 0x7b, 0xe3, 0xb2, 0x0a, 0xa8, 0xb8, 0xc5, 0x8e, 0xc9, 0x12, + 0x4c, 0xdb, 0x68, 0x86, 0xf5, 0x95, 0x0d, 0x29, 0x35, 0xcf, 0x23, 0x86, 0x25, 0x20, 0xa0, 0xc6, + 0xce, 0xeb, 0xd2, 0x32, 0xab, 0xff, 0x94, 0x81, 0x99, 0x5d, 0xdf, 0x7b, 0xc8, 0x4c, 0xfe, 0xca, + 0x7c, 0xad, 0x26, 0x61, 0x09, 0xc2, 0x72, 0x9b, 0x19, 0x4d, 0x49, 0x40, 0xd3, 0xa1, 0xfc, 0x70, + 0xe4, 0xdb, 0x81, 0x65, 0x9b, 0x38, 0x22, 0x21, 0x5d, 0x29, 0x5d, 0x8a, 0xf4, 0xe9, 0x09, 0xd2, + 0xdf, 0x80, 0xb2, 0xcf, 0x1e, 0x30, 0x9f, 0xb9, 0x26, 0xeb, 0xd9, 0x96, 0x36, 0x83, 0xe7, 0xa5, + 0x58, 0xb7, 0x6d, 0x35, 0x0f, 0xb0, 0xca, 0xfe, 0x49, 0x4c, 0x13, 0x28, 0x27, 0x0a, 0xb7, 0xd4, + 0x4c, 0x92, 0xfd, 0x2c, 0x51, 0xd3, 0xc1, 0xd5, 0x1c, 0x59, 0x81, 0xa5, 0xb1, 0x43, 0xea, 0x2c, + 0xaf, 0xe5, 0xf4, 0x5f, 0xb2, 0x90, 0xdf, 0xa4, 0xdc, 0x3c, 0x38, 0x81, 0xaf, 0x53, 0x7a, 0x40, + 0x56, 0xa1, 0x34, 0x0c, 0x49, 0x46, 0x8e, 0xb2, 0xe8, 0x01, 0x52, 0x25, 0x18, 0x5a, 0x80, 0xbc, + 0xc5, 0x5c, 0x6f, 0x20, 0xe7, 0x2d, 0x14, 0x52, 0x9c, 0xe4, 0x27, 0x38, 0xf9, 0x10, 0x20, 0xe0, + 0xd4, 0xe7, 0x3d, 0x8b, 0x72, 0x86, 0x8c, 0x95, 0xae, 0xaf, 0xd4, 0xc3, 0xdd, 0xad, 0x47, 0xbb, + 0x5b, 0xef, 0x46, 0xbb, 0x6b, 0x14, 0xd1, 0x7a, 0x8b, 0x72, 0x46, 0xde, 0x87, 0x02, 0x73, 0xad, + 0xd0, 0x71, 0xe6, 0x85, 0x8e, 0x33, 0xcc, 0xb5, 0xd0, 0xed, 0x06, 0x54, 0x44, 0x39, 0x54, 0x70, + 0x81, 0xbe, 0x85, 0x17, 0xfa, 0x96, 0x23, 0x07, 0x0c, 0x40, 0x20, 0xe7, 0x0d, 0x99, 0xab, 0x15, + 0x2f, 0x28, 0x6b, 0x05, 0x03, 0x9f, 0xd3, 0x23, 0x0d, 0xe9, 0x91, 0x6e, 0xde, 0xc7, 0xa6, 0x76, + 0xc7, 0x4d, 0x2d, 0x49, 0x9a, 0xb0, 0xaf, 0xb3, 0x29, 0x52, 0xd5, 0x0c, 0xa9, 0x26, 0x29, 0x51, + 0xb3, 0x04, 0xa2, 0x6e, 0xa8, 0x39, 0x52, 0x49, 0xe4, 0x51, 0xf3, 0x5a, 0x5e, 0xff, 0x5a, 0x81, + 0x0a, 0xee, 0xd6, 0x1e, 0xfb, 0x6a, 0x24, 0xfa, 0x7b, 0xca, 0x6a, 0x2b, 0x27, 0xaf, 0x36, 0x79, + 0x13, 0x2a, 0x2e, 0x3b, 0xe2, 0xbd, 0x40, 0xba, 0x63, 0xc7, 0x73, 0x46, 0x59, 0x28, 0xa3, 0x90, + 0xcd, 0x1a, 0x16, 0xa0, 0xc1, 0xc2, 0x89, 0xa1, 0xa7, 0x75, 0x07, 0x66, 0xe5, 0xf2, 0xc5, 0x28, + 0xce, 0xdc, 0xf1, 0x97, 0x4a, 0xba, 0x8c, 0x49, 0x67, 0xa1, 0x94, 0x8c, 0x34, 0xa3, 0x29, 0xba, + 0x0b, 0x15, 0x1c, 0xdc, 0x38, 0xd7, 0xc4, 0x58, 0x2a, 0xcf, 0x8d, 0xe5, 0xff, 0xc8, 0x37, 0x07, + 0x95, 0x74, 0xb4, 0x82, 0xfe, 0x8f, 0x02, 0x65, 0x4c, 0xb8, 0x49, 0x1d, 0x2a, 0x6b, 0xeb, 0x0b, + 0x39, 0x59, 0x1b, 0x2a, 0x44, 0x2e, 0x0d, 0x66, 0xa8, 0x65, 0xf9, 0x2c, 0x08, 0xe4, 0xf2, 0x44, + 0x22, 0xb9, 0x0c, 0xb3, 0xdc, 0xa7, 0x16, 0xed, 0x3b, 0xac, 0x47, 0x07, 0xde, 0xc8, 0x8d, 0x3e, + 0x1a, 0xd5, 0x48, 0xdd, 0x42, 0x2d, 0xb9, 0x04, 0x55, 0x9f, 0x71, 0xdb, 0x67, 0x56, 0x64, 0x17, + 0xae, 0x53, 0x45, 0x6a, 0xa5, 0xd9, 0x65, 0x98, 0x65, 0x81, 0xe9, 0x7b, 0x8f, 0xc7, 0x76, 0xe1, + 0x76, 0x55, 0x23, 0x75, 0x68, 0xd8, 0x7c, 0x0f, 0x2b, 0xab, 0xc3, 0x3c, 0xcc, 0x49, 0x2c, 0xeb, + 0x31, 0x7e, 0xb2, 0x08, 0x73, 0xb1, 0xb0, 0x2e, 0x8f, 0x55, 0x45, 0x2b, 0xea, 0x3f, 0x2b, 0x50, + 0x0a, 0x79, 0x1e, 0x0d, 0x87, 0xce, 0xf1, 0xd9, 0x55, 0x9f, 0x50, 0x5b, 0xe6, 0x25, 0x6b, 0xcb, + 0x9e, 0x54, 0xdb, 0x15, 0x50, 0x4d, 0xc1, 0xb5, 0xe3, 0x4c, 0x92, 0x30, 0x1b, 0xeb, 0x65, 0x75, + 0x8b, 0xe3, 0x39, 0x19, 0xe3, 0x03, 0x7d, 0x04, 0x95, 0xbb, 0xbe, 0xbd, 0x6f, 0xbb, 0xdd, 0xa3, + 0x6d, 0xd7, 0x62, 0x47, 0x67, 0x4f, 0xe4, 0xe4, 0x17, 0x62, 0x09, 0xa6, 0x03, 0x6f, 0xe4, 0x9b, + 0x4c, 0xc2, 0x93, 0x52, 0x73, 0x15, 0x93, 0x9d, 0x83, 0x45, 0x98, 0x4f, 0xbe, 0x8c, 0xd7, 0xa5, + 0x71, 0x49, 0xff, 0x4e, 0x91, 0xd3, 0xd9, 0xf6, 0x5c, 0xee, 0x53, 0x93, 0x9f, 0xcd, 0x5b, 0x0a, + 0x54, 0x66, 0x02, 0xd4, 0x0a, 0x14, 0x4c, 0x19, 0x45, 0xc2, 0x88, 0xe5, 0x66, 0x03, 0x81, 0x5c, + 0x49, 0x55, 0x4d, 0x34, 0x20, 0x63, 0x54, 0x91, 0x29, 0xde, 0x27, 0xca, 0xfa, 0x47, 0xb0, 0x88, + 0xef, 0x89, 0xb6, 0xcf, 0x28, 0xf7, 0xfc, 0x96, 0xe3, 0x78, 0x8f, 0x1d, 0x3b, 0xe0, 0x62, 0x60, + 0x99, 0x2b, 0x3a, 0x64, 0x21, 0xba, 0x82, 0x11, 0x89, 0xcd, 0xc2, 0xbf, 0x22, 0x47, 0xa6, 0x50, + 0xd1, 0xb7, 0x60, 0x1e, 0x1d, 0x98, 0x95, 0x8c, 0x91, 0x9c, 0x75, 0x25, 0x35, 0xeb, 0xcd, 0x79, + 0x84, 0x57, 0x81, 0xe2, 0xd8, 0xa2, 0xaa, 0xb7, 0xa0, 0x80, 0xee, 0x37, 0x19, 0x23, 0xd7, 0x20, + 0xfb, 0x80, 0x31, 0x74, 0x2b, 0x5d, 0x3f, 0x57, 0x0f, 0x6f, 0x71, 0x75, 0x71, 0xcb, 0xab, 0xcb, + 0x5b, 0x5e, 0xbd, 0xed, 0xd9, 0xae, 0x21, 0xac, 0x62, 0x20, 0xb3, 0xfa, 0x2d, 0x20, 0x12, 0xc8, + 0xa6, 0x6f, 0x5b, 0xfb, 0xac, 0x7d, 0x40, 0x6d, 0x97, 0xbc, 0x0e, 0x60, 0x8a, 0x87, 0x1e, 0xde, + 0xce, 0xc2, 0x57, 0x5d, 0x11, 0x35, 0x3b, 0x74, 0xc0, 0x9a, 0x4b, 0x08, 0x46, 0x85, 0x72, 0xca, + 0x4c, 0xd5, 0x7f, 0xcc, 0xc0, 0x9c, 0x7c, 0x6f, 0x75, 0x5c, 0xdf, 0x73, 0x9c, 0x01, 0x73, 0xf9, + 0x8b, 0xdf, 0x26, 0xa9, 0x9e, 0x65, 0x27, 0x7a, 0xd6, 0x86, 0x69, 0x71, 0xa5, 0x1d, 0x05, 0x38, + 0xae, 0xd5, 0xeb, 0xd7, 0xea, 0xcf, 0x5f, 0x6a, 0xeb, 0xcf, 0x25, 0xdd, 0x43, 0x17, 0x43, 0xba, + 0x92, 0x0d, 0x58, 0xa0, 0xc3, 0xa1, 0x63, 0x9b, 0x78, 0x31, 0xec, 0x4d, 0x7c, 0x3c, 0xe7, 0x13, + 0x67, 0x77, 0xa2, 0xef, 0x68, 0x03, 0xe6, 0x59, 0x1c, 0xae, 0x37, 0x71, 0x05, 0x21, 0xe3, 0xa3, + 0xc8, 0xa1, 0xf9, 0x0e, 0x92, 0x72, 0x15, 0x96, 0x61, 0x31, 0x51, 0xee, 0x7a, 0x5c, 0x59, 0xfa, + 0x53, 0xa3, 0x68, 0x73, 0x7a, 0x1b, 0x40, 0x02, 0x7f, 0xe5, 0x06, 0x92, 0xab, 0x7f, 0x29, 0xb0, + 0x7c, 0x4a, 0xf9, 0xe4, 0x0a, 0x5c, 0xda, 0x35, 0xee, 0x7e, 0xd6, 0x69, 0x77, 0x7b, 0x9d, 0x1d, + 0xe3, 0xee, 0xed, 0xdb, 0x77, 0x3a, 0x3b, 0xdd, 0xde, 0x5e, 0xb7, 0xd5, 0xbd, 0xb7, 0xd7, 0xbb, + 0xb7, 0xb3, 0xb7, 0xdb, 0x69, 0x6f, 0xdf, 0xdc, 0xee, 0x6c, 0xa9, 0x53, 0xe4, 0x2d, 0xd0, 0x4f, + 0x37, 0x6d, 0xb5, 0xdb, 0x9d, 0xdd, 0x6e, 0x67, 0x4b, 0x55, 0x48, 0x03, 0xae, 0x9d, 0x6e, 0xd7, + 0xfe, 0xb4, 0xb5, 0xf3, 0x49, 0x67, 0xaf, 0x67, 0x74, 0x3e, 0xbf, 0xd7, 0xd9, 0x13, 0x0e, 0x99, + 0xb3, 0x03, 0x1b, 0x1d, 0x71, 0xd0, 0xd9, 0x52, 0xb3, 0x64, 0x0d, 0x2e, 0x9e, 0x6e, 0xd7, 0xed, + 0x18, 0x77, 0xb6, 0x77, 0x5a, 0xc2, 0x32, 0xb7, 0xf9, 0xc5, 0xaf, 0x4f, 0x6b, 0xca, 0x93, 0xa7, + 0x35, 0xe5, 0xcf, 0xa7, 0x35, 0xe5, 0xdb, 0x67, 0xb5, 0xa9, 0x27, 0xcf, 0x6a, 0x53, 0x7f, 0x3c, + 0xab, 0x4d, 0xdd, 0xbf, 0xb1, 0x6f, 0xf3, 0x83, 0x51, 0xbf, 0x6e, 0x7a, 0x83, 0x06, 0x4e, 0xc9, + 0xdb, 0x2e, 0xe3, 0x8f, 0x3d, 0xff, 0x91, 0x94, 0x1c, 0x66, 0xed, 0x33, 0xbf, 0x71, 0x94, 0xf8, + 0x63, 0xc2, 0xdf, 0x20, 0xf1, 0xf1, 0x0d, 0xc4, 0xcf, 0xd0, 0x34, 0xde, 0x55, 0xde, 0xfd, 0x2f, + 0x00, 0x00, 0xff, 0xff, 0x42, 0x03, 0x26, 0x56, 0x59, 0x0d, 0x00, 0x00, } func (m *CreditType) Marshal() (dAtA []byte, err error) { diff --git a/x/ecocredit/base/types/v1/state_project.go b/x/ecocredit/base/types/v1/state_project.go index d1a8d51f0c..39dc69394b 100644 --- a/x/ecocredit/base/types/v1/state_project.go +++ b/x/ecocredit/base/types/v1/state_project.go @@ -23,8 +23,8 @@ func (m *Project) Validate() error { return ecocredit.ErrParseFailure.Wrapf("admin: %s", err) } - if m.ClassKey == 0 { - return ecocredit.ErrParseFailure.Wrap("class key cannot be zero") + if m.ClassKey != 0 && m.ReferenceId == "" { + return ecocredit.ErrParseFailure.Wrap("class key must be zero unless reference id is set") } if err := base.ValidateJurisdiction(m.Jurisdiction); err != nil { diff --git a/x/ecocredit/base/types/v1/tx.pb.go b/x/ecocredit/base/types/v1/tx.pb.go index c4101e53ce..55138c2bd0 100644 --- a/x/ecocredit/base/types/v1/tx.pb.go +++ b/x/ecocredit/base/types/v1/tx.pb.go @@ -437,15 +437,12 @@ type MsgCreateUnregisteredProject struct { // sub-national-code and postal-code are optional and can be added for // increased precision. Jurisdiction string `protobuf:"bytes,3,opt,name=jurisdiction,proto3" json:"jurisdiction,omitempty"` - // reference_id is any arbitrary string used to reference the project with a - // maximum length of 32 characters. - ReferenceId string `protobuf:"bytes,4,opt,name=reference_id,json=referenceId,proto3" json:"reference_id,omitempty"` // fee is the project creation fee. An equal fee is required if the project // creation fee parameter is set. The provided fee can be greater than the // parameter, but only the amount in the parameter will be charged. // // Since Revision 3 - Fee *types.Coin `protobuf:"bytes,5,opt,name=fee,proto3" json:"fee,omitempty"` + Fee *types.Coin `protobuf:"bytes,4,opt,name=fee,proto3" json:"fee,omitempty"` } func (m *MsgCreateUnregisteredProject) Reset() { *m = MsgCreateUnregisteredProject{} } @@ -502,13 +499,6 @@ func (m *MsgCreateUnregisteredProject) GetJurisdiction() string { return "" } -func (m *MsgCreateUnregisteredProject) GetReferenceId() string { - if m != nil { - return m.ReferenceId - } - return "" -} - func (m *MsgCreateUnregisteredProject) GetFee() *types.Coin { if m != nil { return m.Fee @@ -3499,145 +3489,144 @@ func init() { func init() { proto.RegisterFile("regen/ecocredit/v1/tx.proto", fileDescriptor_2b8ae49f50a3ddbd) } var fileDescriptor_2b8ae49f50a3ddbd = []byte{ - // 2193 bytes of a gzipped FileDescriptorProto + // 2191 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0x4f, 0x6f, 0xdb, 0xc8, - 0x15, 0x5f, 0x4a, 0xb2, 0x2d, 0x3d, 0x39, 0x4e, 0xc2, 0x64, 0x1d, 0x85, 0x8e, 0x65, 0x47, 0x49, - 0x36, 0xce, 0x9f, 0x95, 0x6a, 0x6f, 0xdb, 0x34, 0x29, 0x8a, 0xd4, 0xf6, 0x6e, 0x50, 0x2f, 0xa0, + 0x15, 0x0f, 0x25, 0xd9, 0x96, 0x9e, 0x1c, 0x27, 0x61, 0xb2, 0x8e, 0x42, 0xc7, 0xb2, 0xa3, 0x24, + 0x1b, 0x27, 0x9b, 0x95, 0x6a, 0x6f, 0xdb, 0x34, 0x29, 0x8a, 0xd4, 0xf6, 0x6e, 0x50, 0x2f, 0xa0, 0xdd, 0x85, 0x92, 0x45, 0xd1, 0x45, 0x0b, 0x81, 0x22, 0x27, 0x34, 0x53, 0x89, 0x14, 0xc8, 0x91, - 0xe5, 0xa0, 0x45, 0x81, 0x14, 0x05, 0x7a, 0xdd, 0x5b, 0x81, 0xa2, 0x87, 0x7e, 0x84, 0x7e, 0x87, - 0x5e, 0xda, 0x5b, 0x2e, 0x45, 0x7b, 0x4b, 0x91, 0xb4, 0xe8, 0x37, 0xe8, 0xb9, 0xe0, 0xcc, 0x70, - 0x34, 0x43, 0x71, 0x48, 0x6a, 0xd3, 0x5c, 0x0c, 0xce, 0xcc, 0x9b, 0xf7, 0x7e, 0xef, 0xcd, 0x9b, - 0xf7, 0x67, 0x2c, 0xd8, 0x08, 0x90, 0x83, 0xbc, 0x0e, 0xb2, 0x7c, 0x2b, 0x40, 0xb6, 0x8b, 0x3b, - 0x27, 0xbb, 0x1d, 0x7c, 0xda, 0x1e, 0x07, 0x3e, 0xf6, 0x75, 0x9d, 0x2c, 0xb6, 0xf9, 0x62, 0xfb, - 0x64, 0xd7, 0x68, 0x5a, 0x7e, 0x38, 0xf2, 0xc3, 0xce, 0xc0, 0x0c, 0x51, 0xe7, 0x64, 0x77, 0x80, - 0xb0, 0xb9, 0xdb, 0xb1, 0x7c, 0xd7, 0xa3, 0x7b, 0x8c, 0x4b, 0x6c, 0x7d, 0x14, 0x3a, 0x11, 0xaf, - 0x51, 0xe8, 0xb0, 0x85, 0x8b, 0x8e, 0xef, 0xf8, 0xe4, 0xb3, 0x13, 0x7d, 0xb1, 0xd9, 0x2d, 0xc7, - 0xf7, 0x9d, 0x21, 0xea, 0x90, 0xd1, 0x60, 0xf2, 0xb4, 0x83, 0xdd, 0x11, 0x0a, 0xb1, 0x39, 0x1a, - 0x33, 0x82, 0x66, 0x0a, 0xc0, 0x10, 0x9b, 0x18, 0x65, 0xac, 0xe3, 0xe7, 0x63, 0x14, 0xd2, 0xf5, - 0xd6, 0x0b, 0x0d, 0xce, 0x75, 0x43, 0x67, 0xdf, 0xb6, 0x0f, 0xc9, 0xfa, 0x93, 0xe7, 0x63, 0xa4, - 0x5f, 0x81, 0x9a, 0x39, 0xc1, 0xc7, 0x7e, 0xe0, 0xe2, 0xe7, 0x0d, 0x6d, 0x5b, 0xdb, 0xa9, 0xf5, - 0x66, 0x13, 0xfa, 0x43, 0xa8, 0x53, 0x5e, 0xfd, 0x88, 0x51, 0xa3, 0xb4, 0xad, 0xed, 0xd4, 0xf7, - 0x9a, 0xed, 0x79, 0x63, 0xb4, 0x67, 0x2c, 0x7b, 0x60, 0xf1, 0xef, 0x07, 0x6b, 0xbf, 0xfe, 0xcf, - 0x9f, 0x6e, 0xcf, 0x18, 0xb6, 0x0c, 0x68, 0x24, 0x21, 0xf4, 0x50, 0x38, 0xf6, 0xbd, 0x10, 0xb5, - 0xfe, 0xac, 0xc1, 0x5a, 0x37, 0x74, 0x0e, 0x03, 0x64, 0x62, 0x74, 0x38, 0x34, 0xc3, 0x50, 0xbf, - 0x08, 0x4b, 0xa6, 0x3d, 0x72, 0x3d, 0x86, 0x8c, 0x0e, 0xf4, 0x06, 0xac, 0xb8, 0x61, 0x38, 0x41, - 0x41, 0xd8, 0x28, 0x6d, 0x97, 0x77, 0x6a, 0xbd, 0x78, 0xa8, 0x1b, 0x50, 0x1d, 0x21, 0x6c, 0xda, - 0x26, 0x36, 0x1b, 0x65, 0xb2, 0x85, 0x8f, 0xf5, 0xbb, 0xa0, 0x0b, 0xba, 0xf4, 0xcd, 0xc1, 0x20, - 0x40, 0x27, 0x8d, 0x0a, 0xa1, 0x3a, 0x37, 0x83, 0xbc, 0x4f, 0xe6, 0xf5, 0x3b, 0x50, 0x7e, 0x8a, - 0x50, 0x63, 0x89, 0x68, 0x7c, 0xb9, 0x4d, 0x8f, 0xb2, 0x1d, 0x1d, 0x75, 0x9b, 0x1d, 0x75, 0xfb, - 0xd0, 0x77, 0xbd, 0x5e, 0x44, 0xf5, 0x00, 0x22, 0x2d, 0x29, 0xb8, 0xd6, 0x47, 0xb0, 0x2e, 0x2b, - 0x11, 0xeb, 0xa7, 0x5f, 0x86, 0xaa, 0x15, 0x4d, 0xf4, 0x5d, 0x9b, 0xe9, 0xb3, 0x42, 0xc6, 0x47, - 0x76, 0xeb, 0x15, 0x3d, 0x1a, 0xba, 0xeb, 0x8b, 0xc0, 0x7f, 0x86, 0x2c, 0xac, 0x50, 0x5e, 0xe4, - 0x52, 0x92, 0xb8, 0x64, 0x6a, 0xdf, 0x82, 0xd5, 0x67, 0x93, 0xc0, 0x0d, 0x6d, 0xd7, 0xc2, 0xae, - 0xef, 0x31, 0xbd, 0xa5, 0x39, 0xfd, 0x2a, 0xac, 0x06, 0xe8, 0x29, 0x0a, 0x90, 0x67, 0xa1, 0x88, - 0xfd, 0x12, 0xa1, 0xa9, 0xf3, 0xb9, 0x23, 0x3b, 0x36, 0xcb, 0xf2, 0xc2, 0x66, 0xb9, 0x4f, 0x0e, - 0x5e, 0x52, 0x90, 0x1b, 0x66, 0x13, 0x60, 0x4c, 0xa7, 0x66, 0xa6, 0xa9, 0xb1, 0x99, 0x23, 0xbb, - 0xf5, 0x52, 0x83, 0x2b, 0x7c, 0xef, 0x97, 0x5e, 0x80, 0x1c, 0x37, 0xc4, 0x28, 0x40, 0x76, 0xb6, - 0xa1, 0x44, 0x6b, 0x94, 0x72, 0xac, 0x51, 0x2e, 0x60, 0x8d, 0x8a, 0xd2, 0x1a, 0x8b, 0x3b, 0xc9, - 0x27, 0x70, 0x3d, 0x4b, 0xa3, 0xa2, 0x96, 0xf9, 0xab, 0x68, 0x99, 0xcf, 0x83, 0x2f, 0xc7, 0xb6, - 0x89, 0xd1, 0xfe, 0x78, 0x3c, 0x74, 0x2d, 0x93, 0xe8, 0x70, 0x0d, 0xce, 0xc4, 0xfb, 0x45, 0x0b, - 0xad, 0xb2, 0xc9, 0x7d, 0x62, 0x28, 0x59, 0x48, 0x29, 0x21, 0x44, 0x72, 0xb8, 0xb2, 0xda, 0xe1, - 0x2a, 0x09, 0x13, 0x1b, 0x50, 0x9d, 0xba, 0xf8, 0xd8, 0x0e, 0xcc, 0x29, 0x31, 0x50, 0xb5, 0xc7, - 0xc7, 0x0f, 0xf4, 0xc8, 0x14, 0x32, 0xb2, 0xd6, 0x07, 0x82, 0x49, 0x52, 0x54, 0xe1, 0x51, 0xe2, - 0x8d, 0x06, 0x46, 0x37, 0x74, 0x28, 0x01, 0xb3, 0xd7, 0x27, 0x5e, 0xe0, 0x0f, 0x87, 0x23, 0xe4, - 0x61, 0x7d, 0x1d, 0x96, 0x69, 0x30, 0x60, 0xaa, 0xb2, 0xd1, 0x5b, 0x28, 0xf9, 0x29, 0x80, 0x87, - 0xa6, 0xfd, 0x28, 0xd2, 0x4e, 0x42, 0xa2, 0xe6, 0xda, 0xde, 0x9d, 0xb4, 0x10, 0x38, 0x07, 0xe6, - 0x31, 0xd9, 0xd2, 0xab, 0x79, 0x68, 0x4a, 0x3f, 0x25, 0x83, 0x2d, 0xc9, 0x06, 0x7b, 0x50, 0x8f, - 0x8c, 0xc2, 0xe0, 0xb6, 0xae, 0x43, 0x4b, 0xad, 0x24, 0xb7, 0xc5, 0xef, 0xca, 0x42, 0xc4, 0x3c, - 0x30, 0xb1, 0x75, 0xfc, 0x4d, 0xf5, 0xff, 0x01, 0x54, 0x23, 0x42, 0xd3, 0xb3, 0x50, 0xa3, 0xbc, - 0x5d, 0xde, 0xa9, 0xef, 0x5d, 0x4d, 0x53, 0x91, 0xc8, 0x38, 0x62, 0x84, 0x3d, 0xbe, 0x25, 0xd3, - 0x11, 0x1e, 0x02, 0x84, 0xd8, 0x0c, 0x70, 0x3f, 0xd2, 0x85, 0xdd, 0x15, 0xa3, 0x4d, 0x93, 0x5d, - 0x3b, 0x4e, 0x76, 0xed, 0x27, 0x71, 0xb2, 0x3b, 0xa8, 0x7c, 0xfd, 0x6a, 0x4b, 0xeb, 0xd5, 0xc8, - 0x9e, 0x8f, 0x4d, 0x8c, 0xf4, 0xef, 0x43, 0x15, 0x79, 0x36, 0xdd, 0xbe, 0x5c, 0x70, 0xfb, 0x0a, - 0xf2, 0x6c, 0xb2, 0x59, 0x87, 0x8a, 0x3f, 0x46, 0x5e, 0x63, 0x85, 0xb8, 0x20, 0xf9, 0xd6, 0xef, - 0x43, 0xcd, 0x0f, 0x5c, 0xc7, 0xf5, 0xfa, 0xf8, 0xb4, 0x51, 0x25, 0x1c, 0xaf, 0xa4, 0x69, 0xfb, - 0x39, 0x21, 0x7a, 0x72, 0xda, 0xab, 0xfa, 0xec, 0x4b, 0xf2, 0x93, 0x9a, 0xe4, 0x27, 0xf2, 0xf9, - 0xdd, 0x17, 0xb2, 0x00, 0x31, 0x1a, 0xbf, 0xd2, 0x5b, 0x50, 0x1f, 0x44, 0x13, 0x7d, 0x1b, 0x79, - 0xfe, 0x88, 0x9d, 0x12, 0x90, 0xa9, 0x8f, 0xa3, 0x99, 0xd6, 0xdf, 0x34, 0xb8, 0xd0, 0x0d, 0x9d, - 0xae, 0xeb, 0x61, 0xb2, 0x93, 0x66, 0xca, 0x50, 0x79, 0xb2, 0x09, 0x86, 0xa5, 0x24, 0xc3, 0xb7, - 0x3d, 0x5b, 0xc9, 0x5a, 0x95, 0x45, 0xac, 0x25, 0x9b, 0x64, 0x13, 0x36, 0x52, 0xd4, 0xe2, 0xbe, - 0xfc, 0x04, 0x56, 0xbb, 0xa1, 0xf3, 0x18, 0x99, 0xc3, 0x6c, 0x47, 0xce, 0x53, 0x57, 0x16, 0xba, - 0x0e, 0x17, 0x45, 0xae, 0x5c, 0xda, 0x7f, 0x4b, 0xb0, 0x42, 0x16, 0x3c, 0x3b, 0x92, 0x14, 0x22, - 0xcf, 0x9e, 0x49, 0xa2, 0xa3, 0xa8, 0x34, 0x0a, 0x90, 0xe5, 0x8e, 0x5d, 0xe4, 0xe1, 0xf8, 0xc6, - 0xf0, 0x09, 0x7d, 0x1f, 0x56, 0xa8, 0xee, 0x21, 0x33, 0xea, 0xcd, 0x34, 0xa3, 0x30, 0x19, 0xed, - 0xe8, 0x4f, 0xac, 0x71, 0xbc, 0xcf, 0xf8, 0x97, 0x06, 0x75, 0x61, 0x21, 0xd7, 0x35, 0xf4, 0x9b, - 0x70, 0x16, 0x07, 0xa6, 0x6d, 0x0e, 0x86, 0xa8, 0x6f, 0x8e, 0xfc, 0x09, 0xc7, 0xb5, 0x16, 0x4f, - 0xef, 0x93, 0x59, 0xfd, 0x06, 0xac, 0x05, 0x08, 0xbb, 0x01, 0xb2, 0x63, 0x3a, 0x1a, 0xd4, 0xce, - 0xb0, 0x59, 0x46, 0x76, 0x0f, 0x2e, 0xd1, 0x89, 0x28, 0xaa, 0xf4, 0x53, 0xea, 0x83, 0xf5, 0xd9, - 0xf2, 0xa7, 0x62, 0x6e, 0xbc, 0x03, 0xe7, 0x85, 0x8d, 0x01, 0x32, 0x43, 0xdf, 0x63, 0x01, 0xed, - 0xdc, 0x6c, 0xa1, 0x47, 0xe6, 0xd9, 0x81, 0x50, 0xa3, 0xb6, 0xce, 0xc3, 0x59, 0x66, 0x13, 0x7e, - 0x16, 0x7f, 0xd4, 0xa0, 0xd6, 0x0d, 0x9d, 0x1e, 0xd9, 0x17, 0x25, 0x73, 0x7f, 0xea, 0xf1, 0xc3, - 0xa0, 0x03, 0xfd, 0x3b, 0x33, 0x6b, 0x97, 0x88, 0xb5, 0x37, 0xd4, 0x45, 0xe8, 0xcc, 0xc2, 0x85, - 0xf2, 0xfc, 0x3a, 0x2c, 0x33, 0x05, 0xa8, 0xce, 0x6c, 0xc4, 0xf2, 0x35, 0x11, 0xdf, 0xba, 0x00, - 0xe7, 0x39, 0x42, 0x8e, 0xfb, 0x97, 0x04, 0xf6, 0x61, 0x74, 0x49, 0x86, 0xff, 0x5f, 0xd8, 0x33, - 0x48, 0xe5, 0x1c, 0x48, 0x54, 0x3a, 0x87, 0xe4, 0x93, 0xd0, 0x41, 0xd3, 0x06, 0x29, 0x3e, 0x69, - 0x86, 0x5f, 0xb8, 0x92, 0xdc, 0x80, 0x28, 0x69, 0xb1, 0x9a, 0x81, 0x95, 0x92, 0x1e, 0x9a, 0x12, - 0x6e, 0x52, 0x21, 0x43, 0x2f, 0x75, 0x52, 0x20, 0xc7, 0xf3, 0x07, 0x0d, 0xde, 0x97, 0xd7, 0x8f, - 0x58, 0xa5, 0xbe, 0x30, 0xa4, 0x2d, 0xa8, 0x9b, 0xb6, 0xdd, 0x8f, 0x0b, 0xff, 0x32, 0x29, 0xfc, - 0xc1, 0xb4, 0xed, 0x98, 0x23, 0xf1, 0xf9, 0x91, 0x7f, 0x82, 0x38, 0x4d, 0x85, 0xd0, 0x9c, 0xa1, - 0xb3, 0x8c, 0x4c, 0x42, 0xbf, 0x05, 0x9b, 0xa9, 0xe8, 0x38, 0xfe, 0x53, 0x12, 0xc6, 0x05, 0x82, - 0x6e, 0x9c, 0xd5, 0x16, 0xc6, 0x7f, 0x15, 0x56, 0x23, 0x93, 0x26, 0x0a, 0xf4, 0xba, 0x87, 0xa6, - 0x31, 0x4f, 0x09, 0xda, 0x36, 0x34, 0xd3, 0x25, 0x73, 0x6c, 0x13, 0xc1, 0xb4, 0x5f, 0x88, 0xf5, - 0x5c, 0x3a, 0xb4, 0x9c, 0x02, 0xa0, 0xf0, 0x89, 0x8b, 0x36, 0x13, 0xc5, 0x72, 0x5c, 0xbf, 0x22, - 0x95, 0xbe, 0x44, 0x90, 0x63, 0xb5, 0x1c, 0x68, 0x0b, 0x5a, 0xae, 0x05, 0xdb, 0x2a, 0xf9, 0x1c, - 0xe3, 0xef, 0x69, 0xc8, 0x39, 0x08, 0x5c, 0xdb, 0x51, 0x85, 0x9c, 0x75, 0x58, 0xc6, 0x66, 0xe0, - 0xa0, 0x38, 0xc6, 0xb2, 0x91, 0x9c, 0x16, 0xca, 0xc9, 0xb4, 0x20, 0xdc, 0xf8, 0x4a, 0xf1, 0x1b, - 0x2f, 0xdd, 0xec, 0x17, 0x9a, 0xe0, 0x75, 0x24, 0x6d, 0x71, 0xfb, 0x7d, 0xe3, 0x1a, 0xa0, 0x80, - 0x0d, 0xa5, 0xbc, 0x29, 0xba, 0x9f, 0x04, 0x81, 0x9b, 0x90, 0xc6, 0x1f, 0x6a, 0x41, 0x3e, 0xf9, - 0xaa, 0x42, 0xfa, 0xd8, 0x78, 0xd6, 0x42, 0xee, 0x09, 0x52, 0x82, 0xce, 0xb8, 0x2c, 0x8f, 0x60, - 0x85, 0x9d, 0x3f, 0x41, 0x5a, 0xdf, 0xbb, 0xab, 0x48, 0xae, 0x92, 0xa4, 0xb8, 0x02, 0xef, 0xc5, - 0x9b, 0xf5, 0x1f, 0xc2, 0x12, 0x31, 0x02, 0xab, 0x5b, 0x6e, 0x17, 0xe2, 0x42, 0x2b, 0x05, 0xba, - 0x51, 0xae, 0x7e, 0x96, 0x16, 0xa9, 0x7e, 0x8c, 0xbf, 0x6b, 0xb0, 0x44, 0x6b, 0x19, 0xc9, 0x65, - 0xb4, 0xa4, 0xcb, 0xac, 0xc3, 0xb2, 0x94, 0xcc, 0xd9, 0x28, 0x51, 0x38, 0x97, 0xdf, 0xae, 0x70, - 0xae, 0x2c, 0x5a, 0x38, 0x67, 0xb4, 0x2a, 0xc6, 0x10, 0x56, 0xe2, 0xde, 0x3b, 0xd9, 0x25, 0x6b, - 0xf3, 0x5d, 0x72, 0x32, 0x09, 0x97, 0x52, 0x92, 0x70, 0xc6, 0xd3, 0x85, 0xec, 0x98, 0x5f, 0x91, - 0xe8, 0x22, 0x1d, 0x58, 0xe1, 0xd2, 0x3a, 0x27, 0xd0, 0xb4, 0x7e, 0x0a, 0x3a, 0x7b, 0x9c, 0x8a, - 0xdc, 0x90, 0x14, 0xef, 0x7e, 0x90, 0xf3, 0x42, 0xd6, 0x20, 0xf7, 0x3d, 0x22, 0xe4, 0x3e, 0x4c, - 0x87, 0x73, 0x4f, 0x5f, 0x57, 0x48, 0xdf, 0x9a, 0xe0, 0xce, 0x6f, 0x0e, 0x22, 0x89, 0xf4, 0x31, - 0xc2, 0xe2, 0xea, 0xfe, 0x70, 0xe8, 0x4f, 0x87, 0x6e, 0x88, 0xf3, 0x41, 0x20, 0x2f, 0x2a, 0xff, - 0xa8, 0x52, 0xd5, 0x5e, 0x3c, 0x9c, 0x03, 0x71, 0x03, 0xae, 0x65, 0x88, 0xe1, 0x68, 0xfa, 0x24, - 0xb7, 0xf4, 0x48, 0xe2, 0x7c, 0x27, 0xc6, 0xa0, 0x59, 0x64, 0x5e, 0x00, 0x47, 0xe0, 0x91, 0xf0, - 0x22, 0xe4, 0xbf, 0x47, 0x28, 0xef, 0xb1, 0x92, 0xbd, 0xc6, 0x94, 0x0a, 0xbd, 0xc6, 0x24, 0x01, - 0x6d, 0xc0, 0xe5, 0x39, 0x79, 0x1c, 0xcc, 0x58, 0x28, 0xab, 0x98, 0xe3, 0xbf, 0x63, 0x38, 0x62, - 0x5d, 0x35, 0x93, 0xc8, 0x01, 0x39, 0xf1, 0x33, 0x2a, 0x39, 0x3a, 0x64, 0xd3, 0xfb, 0x70, 0x78, - 0x6c, 0xba, 0x5e, 0x0e, 0xaa, 0x4d, 0x00, 0x2b, 0x22, 0xeb, 0x7b, 0xe6, 0x08, 0xc5, 0x57, 0x80, - 0xcc, 0x7c, 0x66, 0x8e, 0xe6, 0x71, 0xd0, 0x64, 0x9a, 0x2a, 0x88, 0x83, 0x79, 0x46, 0xb0, 0xd2, - 0xb3, 0x7c, 0xd7, 0x78, 0xa8, 0xff, 0xaa, 0x64, 0x71, 0x48, 0x16, 0x69, 0x26, 0x0f, 0x26, 0x81, - 0xd7, 0x8b, 0x42, 0x75, 0x14, 0x62, 0x07, 0x93, 0x60, 0x96, 0xe2, 0xd9, 0x48, 0x19, 0x7a, 0x55, - 0x05, 0x38, 0x0d, 0x45, 0x74, 0x33, 0xeb, 0x2d, 0xb9, 0x90, 0x58, 0xf8, 0xde, 0xbf, 0x2f, 0x41, - 0xb9, 0x1b, 0x3a, 0xfa, 0xcf, 0xa0, 0x2e, 0xbe, 0x65, 0xb7, 0x14, 0xc9, 0x47, 0xa0, 0x31, 0x6e, - 0xe7, 0xd3, 0xf0, 0x68, 0x67, 0xc1, 0x19, 0xf9, 0xbd, 0xf8, 0x7a, 0xe6, 0x66, 0x46, 0x65, 0xdc, - 0x2d, 0x42, 0xc5, 0x85, 0xfc, 0x56, 0x83, 0xcb, 0xea, 0x87, 0xd7, 0x6f, 0x65, 0xf2, 0x4a, 0xd9, - 0x61, 0x7c, 0x6f, 0xd1, 0x1d, 0x29, 0x48, 0xd2, 0x1e, 0x3a, 0xb3, 0x91, 0xa4, 0xec, 0xc8, 0x41, - 0x92, 0xf1, 0x02, 0xa9, 0xbf, 0xd0, 0xe0, 0x92, 0xea, 0xf9, 0xb1, 0xad, 0xe0, 0xaa, 0xa0, 0x37, - 0xbe, 0xbb, 0x18, 0x3d, 0xc7, 0xc0, 0x7d, 0x8b, 0x16, 0x18, 0xd9, 0xbe, 0x45, 0x68, 0x72, 0x7c, - 0x4b, 0x7e, 0xa4, 0x1a, 0xc2, 0xb9, 0xb9, 0xf7, 0x27, 0xd5, 0xfb, 0x46, 0x92, 0xd0, 0xe8, 0x14, - 0x24, 0xe4, 0xd2, 0x7e, 0x0c, 0xb5, 0xd9, 0xbb, 0xcf, 0xb6, 0xf2, 0x19, 0x85, 0x51, 0x18, 0x3b, - 0x79, 0x14, 0x9c, 0xf1, 0x8f, 0xa0, 0x42, 0x5e, 0x78, 0x36, 0x32, 0x9e, 0x66, 0x8c, 0x6b, 0x19, - 0x8b, 0x9c, 0xd3, 0x67, 0xb0, 0xcc, 0xde, 0x27, 0x36, 0x15, 0xe4, 0x74, 0xd9, 0xb8, 0x91, 0xb9, - 0x2c, 0xf2, 0x63, 0x0f, 0x07, 0x2a, 0x7e, 0x74, 0x59, 0xc9, 0x4f, 0x6e, 0xfc, 0xa3, 0x03, 0x9b, - 0xeb, 0xfa, 0x6f, 0x66, 0xfa, 0xd6, 0x8c, 0x50, 0x79, 0x60, 0xaa, 0xb6, 0x5e, 0x0f, 0x40, 0x4f, - 0x69, 0xe9, 0x6f, 0xe5, 0xb3, 0x61, 0xa4, 0xc6, 0x6e, 0x61, 0x52, 0x2e, 0x73, 0x02, 0x17, 0xd2, - 0xfa, 0xf0, 0xdb, 0xf9, 0x9c, 0x62, 0x5a, 0x63, 0xaf, 0x38, 0xed, 0xbc, 0xaa, 0x52, 0x8b, 0x7d, - 0xab, 0xc8, 0xb5, 0xa5, 0xc6, 0xdd, 0x2d, 0x4c, 0xca, 0x65, 0xfe, 0x02, 0xde, 0x4f, 0x6f, 0x9f, - 0xef, 0x16, 0xe1, 0xc5, 0xd5, 0xfd, 0xf6, 0x22, 0xd4, 0xf3, 0x76, 0x96, 0x3b, 0xcf, 0x6c, 0x3b, - 0x4b, 0xb4, 0x39, 0x76, 0x4e, 0x6d, 0x27, 0xa3, 0x0b, 0xc1, 0xba, 0xf1, 0xcd, 0xcc, 0x26, 0x4d, - 0x79, 0x21, 0xe4, 0x4e, 0x34, 0xca, 0x8e, 0x72, 0x17, 0x7a, 0xbd, 0x48, 0xef, 0x67, 0x14, 0xea, - 0x33, 0x45, 0x21, 0xf2, 0x7f, 0xd3, 0x55, 0x42, 0x24, 0x2a, 0xa5, 0x90, 0xd4, 0x7f, 0x8b, 0xeb, - 0xbf, 0xd1, 0xa0, 0xa1, 0xec, 0x0b, 0x3a, 0xca, 0xe0, 0x95, 0xbe, 0xc1, 0xb8, 0xb7, 0xe0, 0x06, - 0x0e, 0xc3, 0x85, 0xb3, 0xc9, 0xce, 0xe8, 0x83, 0x0c, 0x3d, 0x04, 0x3a, 0xa3, 0x5d, 0x8c, 0x4e, - 0xbc, 0x73, 0x29, 0xad, 0xc7, 0x2d, 0x65, 0x64, 0x4d, 0x92, 0x2a, 0xef, 0x9c, 0xba, 0xdf, 0xd0, - 0x9f, 0xc2, 0x5a, 0xa2, 0xd9, 0xb8, 0x91, 0x1f, 0x2d, 0x1e, 0x21, 0x64, 0x7c, 0x58, 0x88, 0x6c, - 0x3e, 0x50, 0x0b, 0x7d, 0xc4, 0xcd, 0x22, 0x17, 0x35, 0x92, 0xd5, 0x29, 0x48, 0x28, 0x46, 0x92, - 0xf4, 0x26, 0x21, 0xc3, 0x05, 0xe7, 0xa9, 0x95, 0x91, 0x24, 0xb3, 0x2f, 0x20, 0x8e, 0xab, 0xec, - 0x0a, 0x3a, 0x99, 0x47, 0x94, 0x82, 0xe1, 0xde, 0x82, 0x1b, 0xc4, 0xea, 0x62, 0xd6, 0x08, 0xa8, - 0xaa, 0x0b, 0x4e, 0xa1, 0xac, 0x2e, 0xe6, 0xea, 0xfc, 0x83, 0x9f, 0xfc, 0xe5, 0x75, 0x53, 0x7b, - 0xf9, 0xba, 0xa9, 0xfd, 0xf3, 0x75, 0x53, 0xfb, 0xfa, 0x4d, 0xf3, 0xbd, 0x97, 0x6f, 0x9a, 0xef, - 0xfd, 0xe3, 0x4d, 0xf3, 0xbd, 0xaf, 0x1e, 0x3a, 0x2e, 0x3e, 0x9e, 0x0c, 0xda, 0x96, 0x3f, 0xea, - 0x10, 0x6e, 0x1f, 0x7a, 0x08, 0x4f, 0xfd, 0xe0, 0xe7, 0x6c, 0x34, 0x44, 0xb6, 0x83, 0x82, 0xce, - 0xa9, 0xf0, 0x5b, 0x1d, 0xf2, 0x23, 0x22, 0xf2, 0x6b, 0x9d, 0xce, 0xc9, 0xee, 0x60, 0x99, 0xbc, - 0xcf, 0x7c, 0xf4, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xd0, 0xd0, 0xc0, 0x94, 0x24, 0x00, - 0x00, + 0xe5, 0xa0, 0x45, 0x81, 0x14, 0x05, 0x7a, 0xdd, 0x5b, 0x81, 0xa2, 0x87, 0x7e, 0x81, 0x02, 0xfd, + 0x0e, 0xbd, 0xb4, 0xb7, 0xbd, 0x14, 0xed, 0x2d, 0x45, 0xd2, 0xa2, 0xdf, 0xa0, 0xe7, 0x82, 0x33, + 0xc3, 0xd1, 0x0c, 0xc5, 0x21, 0xa9, 0xcd, 0xe6, 0x62, 0x70, 0x66, 0xde, 0xbc, 0xf7, 0x7b, 0x6f, + 0x66, 0xde, 0x3f, 0x0b, 0x36, 0x02, 0xe4, 0x20, 0xaf, 0x83, 0x2c, 0xdf, 0x0a, 0x90, 0xed, 0xe2, + 0xce, 0xc9, 0x6e, 0x07, 0x9f, 0xb6, 0xc7, 0x81, 0x8f, 0x7d, 0x5d, 0x27, 0x8b, 0x6d, 0xbe, 0xd8, + 0x3e, 0xd9, 0x35, 0x9a, 0x96, 0x1f, 0x8e, 0xfc, 0xb0, 0x33, 0x30, 0x43, 0xd4, 0x39, 0xd9, 0x1d, + 0x20, 0x6c, 0xee, 0x76, 0x2c, 0xdf, 0xf5, 0xe8, 0x1e, 0xe3, 0x32, 0x5b, 0x1f, 0x85, 0x4e, 0xc4, + 0x6b, 0x14, 0x3a, 0x6c, 0xe1, 0x92, 0xe3, 0x3b, 0x3e, 0xf9, 0xec, 0x44, 0x5f, 0x6c, 0x76, 0xcb, + 0xf1, 0x7d, 0x67, 0x88, 0x3a, 0x64, 0x34, 0x98, 0x3c, 0xed, 0x60, 0x77, 0x84, 0x42, 0x6c, 0x8e, + 0xc6, 0x8c, 0xa0, 0x99, 0x02, 0x30, 0xc4, 0x26, 0x46, 0x19, 0xeb, 0xf8, 0xf9, 0x18, 0x85, 0x74, + 0xbd, 0xf5, 0x42, 0x83, 0xf3, 0xdd, 0xd0, 0xd9, 0xb7, 0xed, 0x43, 0xb2, 0xfe, 0xe4, 0xf9, 0x18, + 0xe9, 0x57, 0xa1, 0x66, 0x4e, 0xf0, 0xb1, 0x1f, 0xb8, 0xf8, 0x79, 0x43, 0xdb, 0xd6, 0x76, 0x6a, + 0xbd, 0xd9, 0x84, 0xfe, 0x10, 0xea, 0x94, 0x57, 0x3f, 0x62, 0xd4, 0x28, 0x6d, 0x6b, 0x3b, 0xf5, + 0xbd, 0x66, 0x7b, 0xde, 0x18, 0xed, 0x19, 0xcb, 0x1e, 0x58, 0xfc, 0xfb, 0xc1, 0xda, 0xaf, 0xff, + 0xfb, 0xe7, 0x3b, 0x33, 0x86, 0x2d, 0x03, 0x1a, 0x49, 0x08, 0x3d, 0x14, 0x8e, 0x7d, 0x2f, 0x44, + 0xad, 0xbf, 0x68, 0xb0, 0xd6, 0x0d, 0x9d, 0xc3, 0x00, 0x99, 0x18, 0x1d, 0x0e, 0xcd, 0x30, 0xd4, + 0x2f, 0xc1, 0x92, 0x69, 0x8f, 0x5c, 0x8f, 0x21, 0xa3, 0x03, 0xbd, 0x01, 0x2b, 0x6e, 0x18, 0x4e, + 0x50, 0x10, 0x36, 0x4a, 0xdb, 0xe5, 0x9d, 0x5a, 0x2f, 0x1e, 0xea, 0x06, 0x54, 0x47, 0x08, 0x9b, + 0xb6, 0x89, 0xcd, 0x46, 0x99, 0x6c, 0xe1, 0x63, 0xfd, 0x2e, 0xe8, 0x82, 0x2e, 0x7d, 0x73, 0x30, + 0x08, 0xd0, 0x49, 0xa3, 0x42, 0xa8, 0xce, 0xcf, 0x20, 0xef, 0x93, 0x79, 0xfd, 0x3d, 0x28, 0x3f, + 0x45, 0xa8, 0xb1, 0x44, 0x34, 0xbe, 0xd2, 0xa6, 0x47, 0xd9, 0x8e, 0x8e, 0xba, 0xcd, 0x8e, 0xba, + 0x7d, 0xe8, 0xbb, 0x5e, 0x2f, 0xa2, 0x7a, 0x00, 0x91, 0x96, 0x14, 0x5c, 0xeb, 0x03, 0x58, 0x97, + 0x95, 0x88, 0xf5, 0xd3, 0xaf, 0x40, 0xd5, 0x8a, 0x26, 0xfa, 0xae, 0xcd, 0xf4, 0x59, 0x21, 0xe3, + 0x23, 0xbb, 0xf5, 0x92, 0x1e, 0x0d, 0xdd, 0xf5, 0x59, 0xe0, 0x3f, 0x43, 0x16, 0x56, 0x28, 0x2f, + 0x72, 0x29, 0x49, 0x5c, 0x32, 0xb5, 0x6f, 0xc1, 0xea, 0xb3, 0x49, 0xe0, 0x86, 0xb6, 0x6b, 0x61, + 0xd7, 0xf7, 0x98, 0xde, 0xd2, 0x9c, 0x7e, 0x0d, 0x56, 0x03, 0xf4, 0x14, 0x05, 0xc8, 0xb3, 0x50, + 0xc4, 0x7e, 0x89, 0xd0, 0xd4, 0xf9, 0xdc, 0x91, 0x1d, 0x9b, 0x65, 0x79, 0x61, 0xb3, 0xdc, 0x27, + 0x07, 0x2f, 0x29, 0xc8, 0x0d, 0xb3, 0x09, 0x30, 0xa6, 0x53, 0x33, 0xd3, 0xd4, 0xd8, 0xcc, 0x91, + 0xdd, 0xfa, 0x93, 0x06, 0x57, 0xf9, 0xde, 0xcf, 0xbd, 0x00, 0x39, 0x6e, 0x88, 0x51, 0x80, 0xec, + 0x6c, 0x43, 0x89, 0xd6, 0x28, 0xe5, 0x58, 0xa3, 0x9c, 0x62, 0x0d, 0xa6, 0x6a, 0x65, 0x61, 0x55, + 0x3f, 0x82, 0x1b, 0x59, 0x70, 0x8b, 0xaa, 0xfd, 0x37, 0x51, 0xed, 0x4f, 0x83, 0xcf, 0xc7, 0xb6, + 0x89, 0xd1, 0xfe, 0x78, 0x3c, 0x74, 0x2d, 0x93, 0x00, 0xbc, 0x0e, 0x67, 0xe3, 0xfd, 0xa2, 0xfa, + 0xab, 0x6c, 0x72, 0x9f, 0x58, 0x41, 0x16, 0x52, 0x4a, 0x08, 0x91, 0x6e, 0x53, 0x59, 0x7d, 0x9b, + 0x2a, 0x09, 0xfb, 0x19, 0x50, 0x9d, 0xba, 0xf8, 0xd8, 0x0e, 0xcc, 0x29, 0xb9, 0x25, 0xd5, 0x1e, + 0x1f, 0x3f, 0xd0, 0x23, 0x53, 0xc8, 0xc8, 0x5a, 0xef, 0x0a, 0x26, 0x49, 0x51, 0x85, 0xbb, 0x80, + 0xd7, 0x1a, 0x18, 0xdd, 0xd0, 0xa1, 0x04, 0xcc, 0x5e, 0x1f, 0x79, 0x81, 0x3f, 0x1c, 0x8e, 0x90, + 0x87, 0xf5, 0x75, 0x58, 0xa6, 0x2f, 0x9d, 0xa9, 0xca, 0x46, 0x6f, 0xa0, 0xe4, 0xc7, 0x00, 0x1e, + 0x9a, 0xf6, 0x23, 0x37, 0x3a, 0x09, 0x89, 0x9a, 0x6b, 0x7b, 0xef, 0xa5, 0xf9, 0xb7, 0x39, 0x30, + 0x8f, 0xc9, 0x96, 0x5e, 0xcd, 0x43, 0x53, 0xfa, 0x29, 0x19, 0x6c, 0x49, 0x36, 0xd8, 0x83, 0x7a, + 0x64, 0x14, 0x06, 0xb7, 0x75, 0x03, 0x5a, 0x6a, 0x25, 0xb9, 0x2d, 0x7e, 0x57, 0x16, 0xdc, 0xe1, + 0x81, 0x89, 0xad, 0xe3, 0xaf, 0xab, 0xff, 0x0f, 0xa0, 0x1a, 0x11, 0x9a, 0x9e, 0x85, 0x1a, 0xe5, + 0xed, 0xf2, 0x4e, 0x7d, 0xef, 0x5a, 0x9a, 0x8a, 0x44, 0xc6, 0x11, 0x23, 0xec, 0xf1, 0x2d, 0x99, + 0x17, 0xe1, 0x21, 0x40, 0x88, 0xcd, 0x00, 0xf7, 0x23, 0x5d, 0x98, 0xb7, 0x34, 0xda, 0x34, 0x92, + 0xb5, 0xe3, 0x48, 0xd6, 0x7e, 0x12, 0x47, 0xb2, 0x83, 0xca, 0x97, 0x2f, 0xb7, 0xb4, 0x5e, 0x8d, + 0xec, 0xf9, 0xd0, 0xc4, 0x48, 0xff, 0x3e, 0x54, 0x91, 0x67, 0xd3, 0xed, 0xcb, 0x05, 0xb7, 0xaf, + 0x20, 0xcf, 0x26, 0x9b, 0x75, 0xa8, 0xf8, 0x63, 0xe4, 0x35, 0x56, 0xc8, 0x15, 0x24, 0xdf, 0xfa, + 0x7d, 0xa8, 0xf9, 0x81, 0xeb, 0xb8, 0x5e, 0x1f, 0x9f, 0x36, 0xaa, 0x84, 0xe3, 0xd5, 0x34, 0x6d, + 0x3f, 0x25, 0x44, 0x4f, 0x4e, 0x7b, 0x55, 0x9f, 0x7d, 0x49, 0xf7, 0xa4, 0x26, 0xdd, 0x13, 0xf9, + 0xfc, 0xee, 0x0b, 0x2e, 0x9e, 0x18, 0x8d, 0x3f, 0xe9, 0x2d, 0xa8, 0x0f, 0xa2, 0x89, 0xbe, 0x8d, + 0x3c, 0x7f, 0xc4, 0x4e, 0x09, 0xc8, 0xd4, 0x87, 0xd1, 0x4c, 0xeb, 0xef, 0x1a, 0x5c, 0xec, 0x86, + 0x4e, 0xd7, 0xf5, 0x30, 0xd9, 0x49, 0xc3, 0x60, 0xa8, 0x3c, 0xd9, 0x04, 0xc3, 0x52, 0x92, 0xe1, + 0x9b, 0x9e, 0xad, 0x64, 0xad, 0xca, 0x22, 0xd6, 0x92, 0x4d, 0xb2, 0x09, 0x1b, 0x29, 0x6a, 0xf1, + 0xbb, 0xfc, 0x04, 0x56, 0xbb, 0xa1, 0xf3, 0x18, 0x99, 0xc3, 0xec, 0x8b, 0x9c, 0xa7, 0xae, 0x2c, + 0x74, 0x1d, 0x2e, 0x89, 0x5c, 0xb9, 0xb4, 0xff, 0x95, 0x60, 0x85, 0x2c, 0x78, 0x76, 0x24, 0x29, + 0x44, 0x9e, 0x3d, 0x93, 0x44, 0x47, 0x51, 0xde, 0x13, 0x20, 0xcb, 0x1d, 0xbb, 0xc8, 0xc3, 0xf1, + 0x8b, 0xe1, 0x13, 0xfa, 0x3e, 0xac, 0x50, 0xdd, 0x43, 0x66, 0xd4, 0x5b, 0x69, 0x46, 0x61, 0x32, + 0xda, 0xd1, 0x9f, 0x58, 0xe3, 0x78, 0x9f, 0xf1, 0x6f, 0x0d, 0xea, 0xc2, 0x42, 0xee, 0xd5, 0xd0, + 0x6f, 0xc1, 0x39, 0x1c, 0x98, 0xb6, 0x39, 0x18, 0xa2, 0xbe, 0x39, 0xf2, 0x27, 0x1c, 0xd7, 0x5a, + 0x3c, 0xbd, 0x4f, 0x66, 0xf5, 0x9b, 0xb0, 0x16, 0x20, 0xec, 0x06, 0xc8, 0x8e, 0xe9, 0xa8, 0x53, + 0x3b, 0xcb, 0x66, 0x19, 0xd9, 0x3d, 0xb8, 0x4c, 0x27, 0x22, 0xaf, 0xd2, 0x4f, 0x09, 0xfe, 0xeb, + 0xb3, 0xe5, 0x8f, 0xe5, 0xc0, 0x77, 0x41, 0xd8, 0x18, 0x20, 0x33, 0xf4, 0x3d, 0xe6, 0xd0, 0xce, + 0xcf, 0x16, 0x7a, 0x64, 0x9e, 0x1d, 0x08, 0x35, 0x6a, 0xeb, 0x02, 0x9c, 0x63, 0x36, 0xe1, 0x67, + 0xf1, 0x47, 0x0d, 0x6a, 0xdd, 0xd0, 0xe9, 0x91, 0x7d, 0x51, 0xa4, 0xf6, 0xa7, 0x1e, 0x3f, 0x0c, + 0x3a, 0xd0, 0xbf, 0x33, 0xb3, 0x76, 0x89, 0x58, 0x7b, 0x43, 0x9d, 0x61, 0xce, 0x2c, 0x5c, 0x28, + 0x88, 0xaf, 0xc3, 0x32, 0x53, 0x80, 0xea, 0xcc, 0x46, 0x2c, 0x5e, 0x13, 0xf1, 0xad, 0x8b, 0x70, + 0x81, 0x23, 0xe4, 0xb8, 0x7f, 0x49, 0x60, 0x1f, 0x46, 0x8f, 0x64, 0xf8, 0xcd, 0xc2, 0x9e, 0x41, + 0x2a, 0xe7, 0x40, 0xa2, 0xd2, 0x39, 0x24, 0x9f, 0xb8, 0x0e, 0x1a, 0x36, 0x48, 0x66, 0x49, 0x23, + 0xfc, 0xc2, 0x69, 0xe2, 0x06, 0x44, 0x41, 0x8b, 0xe5, 0x0c, 0x2c, 0x4f, 0xf4, 0xd0, 0x94, 0x70, + 0x93, 0x12, 0x19, 0xfa, 0xa8, 0x93, 0x02, 0x39, 0x9e, 0x3f, 0x68, 0xf0, 0x8e, 0xbc, 0x7e, 0xc4, + 0xd2, 0xf0, 0x85, 0x21, 0x6d, 0x41, 0xdd, 0xb4, 0xed, 0x7e, 0x9c, 0xd5, 0x97, 0x49, 0x56, 0x0f, + 0xa6, 0x6d, 0xc7, 0x1c, 0xc9, 0x9d, 0x1f, 0xf9, 0x27, 0x88, 0xd3, 0x54, 0x08, 0xcd, 0x59, 0x3a, + 0xcb, 0xc8, 0x24, 0xf4, 0x5b, 0xb0, 0x99, 0x8a, 0x8e, 0xe3, 0x3f, 0x25, 0x6e, 0x5c, 0x20, 0xe8, + 0xc6, 0x51, 0x6d, 0x61, 0xfc, 0xd7, 0x60, 0x35, 0x32, 0x69, 0x22, 0xfb, 0xae, 0x7b, 0x68, 0x1a, + 0xf3, 0x94, 0xa0, 0x6d, 0x43, 0x33, 0x5d, 0x32, 0xc7, 0x36, 0x11, 0x4c, 0xfb, 0x99, 0x98, 0xcf, + 0xa5, 0x43, 0xcb, 0x49, 0x00, 0x0a, 0x9f, 0xb8, 0x68, 0x33, 0x51, 0x2c, 0xc7, 0xf5, 0x2b, 0x92, + 0xc6, 0x4b, 0x04, 0x39, 0x56, 0xcb, 0x81, 0xb6, 0xa0, 0xe5, 0x5a, 0xb0, 0xad, 0x92, 0xcf, 0x31, + 0xfe, 0x9e, 0xba, 0x9c, 0x83, 0xc0, 0xb5, 0x1d, 0x95, 0xcb, 0x59, 0x87, 0x65, 0x6c, 0x06, 0x0e, + 0x8a, 0x7d, 0x2c, 0x1b, 0xc9, 0x61, 0xa1, 0x9c, 0x0c, 0x0b, 0xc2, 0x8b, 0xaf, 0x14, 0x7f, 0xf1, + 0xd2, 0xcb, 0x7e, 0xa1, 0x09, 0xb7, 0x8e, 0x84, 0x2d, 0x6e, 0xbf, 0xaf, 0x9d, 0x03, 0x14, 0xb0, + 0xa1, 0x14, 0x37, 0xc5, 0xeb, 0x27, 0x41, 0xe0, 0x26, 0xa4, 0xfe, 0x87, 0x5a, 0x90, 0x4f, 0xbe, + 0xac, 0x90, 0x22, 0x35, 0x9e, 0xb5, 0x90, 0x7b, 0x82, 0x94, 0xa0, 0x33, 0x1e, 0xcb, 0x23, 0x58, + 0x61, 0xe7, 0x4f, 0x90, 0xd6, 0xf7, 0xee, 0x2a, 0x82, 0xab, 0x24, 0x29, 0xce, 0xc0, 0x7b, 0xf1, + 0x66, 0xfd, 0x87, 0xb0, 0x44, 0x8c, 0xc0, 0xf2, 0x96, 0x3b, 0x85, 0xb8, 0xd0, 0x4c, 0x81, 0x6e, + 0x94, 0xb3, 0x9f, 0xa5, 0x45, 0xb2, 0x1f, 0xe3, 0x1f, 0x1a, 0x2c, 0xd1, 0x5c, 0x46, 0xba, 0x32, + 0x5a, 0xf2, 0xca, 0xac, 0xc3, 0xb2, 0x14, 0xcc, 0xd9, 0x28, 0x91, 0x38, 0x97, 0xdf, 0x2c, 0x71, + 0xae, 0x2c, 0x9a, 0x38, 0x67, 0x94, 0x2a, 0xc6, 0x10, 0x56, 0xe2, 0xc2, 0x3a, 0xd9, 0x10, 0xd0, + 0xe6, 0x1b, 0x02, 0xc9, 0x20, 0x5c, 0x4a, 0x09, 0xc2, 0x19, 0x7d, 0x09, 0xf9, 0x62, 0x7e, 0x41, + 0xbc, 0x8b, 0x74, 0x60, 0x85, 0x53, 0xeb, 0x1c, 0x47, 0xd3, 0xfa, 0x29, 0xe8, 0xac, 0xf3, 0x14, + 0x5d, 0x43, 0x92, 0xbc, 0xfb, 0x41, 0x4e, 0xfb, 0xab, 0x41, 0xde, 0x7b, 0x44, 0xc8, 0xef, 0x30, + 0x1d, 0xce, 0xf5, 0xb5, 0xae, 0x92, 0xba, 0x35, 0xc1, 0x9d, 0xbf, 0x1c, 0x44, 0x02, 0xe9, 0x63, + 0x84, 0xc5, 0xd5, 0xfd, 0xe1, 0xd0, 0x9f, 0x0e, 0xdd, 0x10, 0xe7, 0x83, 0x40, 0x5e, 0x94, 0xfe, + 0x51, 0xa5, 0xaa, 0xbd, 0x78, 0x38, 0x07, 0xe2, 0x26, 0x5c, 0xcf, 0x10, 0xc3, 0xd1, 0xf4, 0x49, + 0x6c, 0xe9, 0x91, 0xc0, 0xf9, 0x56, 0x8c, 0x41, 0xa3, 0xc8, 0xbc, 0x00, 0x8e, 0xc0, 0x23, 0xee, + 0x45, 0x88, 0x7f, 0x8f, 0x50, 0x5e, 0x27, 0x92, 0x75, 0x63, 0x4a, 0x85, 0xba, 0x31, 0x49, 0x40, + 0x1b, 0x70, 0x65, 0x4e, 0x1e, 0x07, 0x33, 0x16, 0xd2, 0x2a, 0x76, 0xf1, 0xdf, 0x32, 0x1c, 0x31, + 0xaf, 0x9a, 0x49, 0xe4, 0x80, 0x9c, 0xb8, 0x47, 0x4a, 0x8e, 0x0e, 0xd9, 0xf4, 0x3d, 0x1c, 0x1e, + 0x9b, 0xae, 0x97, 0x83, 0x6a, 0x13, 0xc0, 0x8a, 0xc8, 0xfa, 0x9e, 0x39, 0x42, 0xf1, 0x13, 0x20, + 0x33, 0x9f, 0x98, 0xa3, 0x79, 0x1c, 0x34, 0x98, 0xa6, 0x0a, 0xe2, 0x60, 0x9e, 0x11, 0xac, 0xf4, + 0x2c, 0xdf, 0x36, 0x1e, 0x7a, 0x7f, 0x55, 0xb2, 0x38, 0x24, 0x8b, 0x14, 0x93, 0x07, 0x93, 0xc0, + 0xeb, 0x45, 0xae, 0x3a, 0x72, 0xb1, 0x83, 0x49, 0x30, 0x0b, 0xf1, 0x6c, 0xa4, 0x74, 0xbd, 0xaa, + 0x04, 0x9c, 0xba, 0x22, 0xba, 0x99, 0xd5, 0x96, 0x5c, 0x48, 0x2c, 0x7c, 0xef, 0x3f, 0x97, 0xa1, + 0xdc, 0x0d, 0x1d, 0xfd, 0x67, 0x50, 0x17, 0x1b, 0xd5, 0x2d, 0x45, 0xf0, 0x11, 0x68, 0x8c, 0x3b, + 0xf9, 0x34, 0xdc, 0xdb, 0x59, 0x70, 0x56, 0x6e, 0x06, 0xdf, 0xc8, 0xdc, 0xcc, 0xa8, 0x8c, 0xbb, + 0x45, 0xa8, 0xb8, 0x90, 0xdf, 0x6a, 0x70, 0x45, 0xdd, 0x55, 0xfd, 0x56, 0x26, 0xaf, 0x94, 0x1d, + 0xc6, 0xf7, 0x16, 0xdd, 0x91, 0x82, 0x24, 0xad, 0xd1, 0x99, 0x8d, 0x24, 0x65, 0x47, 0x0e, 0x92, + 0x8c, 0x0e, 0xa4, 0xfe, 0x42, 0x83, 0xcb, 0xaa, 0xf6, 0x63, 0x5b, 0xc1, 0x55, 0x41, 0x6f, 0x7c, + 0x77, 0x31, 0x7a, 0x8e, 0x81, 0xdf, 0x2d, 0x9a, 0x60, 0x64, 0xdf, 0x2d, 0x42, 0x93, 0x73, 0xb7, + 0xe4, 0x26, 0xd5, 0x10, 0xce, 0xcf, 0xf5, 0x9f, 0x54, 0xfd, 0x8d, 0x24, 0xa1, 0xd1, 0x29, 0x48, + 0xc8, 0xa5, 0xfd, 0x18, 0x6a, 0xb3, 0xbe, 0xcf, 0xb6, 0xb2, 0x8d, 0xc2, 0x28, 0x8c, 0x9d, 0x3c, + 0x0a, 0xce, 0xf8, 0x47, 0x50, 0x21, 0x1d, 0x9e, 0x8d, 0x8c, 0xd6, 0x8c, 0x71, 0x3d, 0x63, 0x91, + 0x73, 0xfa, 0x04, 0x96, 0x59, 0x7f, 0x62, 0x53, 0x41, 0x4e, 0x97, 0x8d, 0x9b, 0x99, 0xcb, 0x22, + 0x3f, 0xd6, 0x38, 0x50, 0xf1, 0xa3, 0xcb, 0x4a, 0x7e, 0x72, 0xe1, 0x1f, 0x1d, 0xd8, 0x5c, 0xd5, + 0x7f, 0x2b, 0xf3, 0x6e, 0xcd, 0x08, 0x95, 0x07, 0xa6, 0x2a, 0xeb, 0xf5, 0x00, 0xf4, 0x94, 0x92, + 0xfe, 0x76, 0x3e, 0x1b, 0x46, 0x6a, 0xec, 0x16, 0x26, 0xe5, 0x32, 0x27, 0x70, 0x31, 0xad, 0x0e, + 0xbf, 0x93, 0xcf, 0x29, 0xa6, 0x35, 0xf6, 0x8a, 0xd3, 0xce, 0xab, 0x2a, 0x95, 0xd8, 0xb7, 0x8b, + 0x3c, 0x5b, 0x6a, 0xdc, 0xdd, 0xc2, 0xa4, 0x5c, 0xe6, 0x2f, 0xe0, 0x9d, 0xf4, 0xf2, 0xf9, 0x6e, + 0x11, 0x5e, 0x5c, 0xdd, 0x6f, 0x2f, 0x42, 0x3d, 0x6f, 0x67, 0xb9, 0xf2, 0xcc, 0xb6, 0xb3, 0x44, + 0x9b, 0x63, 0xe7, 0xd4, 0x72, 0x32, 0x7a, 0x10, 0xac, 0x1a, 0xdf, 0xcc, 0x2c, 0xd2, 0x94, 0x0f, + 0x42, 0xae, 0x44, 0xa3, 0xe8, 0x28, 0x57, 0xa1, 0x37, 0x8a, 0xd4, 0x7e, 0x46, 0xa1, 0x3a, 0x53, + 0x14, 0x22, 0xff, 0xab, 0x5c, 0x25, 0x44, 0xa2, 0x52, 0x0a, 0x49, 0xfd, 0x9f, 0xb7, 0xfe, 0x1b, + 0x0d, 0x1a, 0xca, 0xba, 0xa0, 0xa3, 0x74, 0x5e, 0xe9, 0x1b, 0x8c, 0x7b, 0x0b, 0x6e, 0xe0, 0x30, + 0x5c, 0x38, 0x97, 0xac, 0x8c, 0xde, 0xcd, 0xd0, 0x43, 0xa0, 0x33, 0xda, 0xc5, 0xe8, 0xc4, 0x37, + 0x97, 0x52, 0x7a, 0xdc, 0x56, 0x7a, 0xd6, 0x24, 0xa9, 0xf2, 0xcd, 0xa9, 0xeb, 0x0d, 0xfd, 0x29, + 0xac, 0x25, 0x8a, 0x8d, 0x9b, 0xf9, 0xde, 0xe2, 0x11, 0x42, 0xc6, 0xfb, 0x85, 0xc8, 0xe6, 0x1d, + 0xb5, 0x50, 0x47, 0xdc, 0x2a, 0xf2, 0x50, 0x23, 0x59, 0x9d, 0x82, 0x84, 0xa2, 0x27, 0x49, 0x2f, + 0x12, 0x32, 0xae, 0xe0, 0x3c, 0xb5, 0xd2, 0x93, 0x64, 0xd6, 0x05, 0xe4, 0xe2, 0x2a, 0xab, 0x82, + 0x4e, 0xe6, 0x11, 0xa5, 0x60, 0xb8, 0xb7, 0xe0, 0x06, 0x31, 0xbb, 0x98, 0x15, 0x02, 0xaa, 0xec, + 0x82, 0x53, 0x28, 0xb3, 0x8b, 0xb9, 0x3c, 0xff, 0xe0, 0x27, 0x7f, 0x7d, 0xd5, 0xd4, 0xbe, 0x7a, + 0xd5, 0xd4, 0xfe, 0xf5, 0xaa, 0xa9, 0x7d, 0xf9, 0xba, 0x79, 0xe6, 0xab, 0xd7, 0xcd, 0x33, 0xff, + 0x7c, 0xdd, 0x3c, 0xf3, 0xc5, 0x43, 0xc7, 0xc5, 0xc7, 0x93, 0x41, 0xdb, 0xf2, 0x47, 0x1d, 0xc2, + 0xed, 0x7d, 0x0f, 0xe1, 0xa9, 0x1f, 0xfc, 0x9c, 0x8d, 0x86, 0xc8, 0x76, 0x50, 0xd0, 0x39, 0x15, + 0x7e, 0x88, 0x43, 0x7e, 0x21, 0x44, 0x7e, 0x8a, 0xd3, 0x39, 0xd9, 0x1d, 0x2c, 0x93, 0xfe, 0xcc, + 0x07, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x31, 0x94, 0x34, 0x74, 0x71, 0x24, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3672,7 +3661,8 @@ type MsgClient interface { // CreateOrUpdateApplicaton creates a new project credit class application, updates // the metadata for an existing one when changes have been requested, or withdraws // the application. When an application is withdrawn, its data will be deleted from - // state and the project may apply again to the same credit class in the future. + // state and the project may apply again to the same credit class in the future. Any + // new metadata will be passed to EventUpdateApplication including for withdrawals. // // Since Revision 3 CreateOrUpdateApplication(ctx context.Context, in *MsgCreateOrUpdateApplication, opts ...grpc.CallOption) (*MsgCreateOrUpdateApplicationResponse, error) @@ -3767,8 +3757,8 @@ type MsgClient interface { // the scope of the provided credit class, the credits will be minted to the // existing credit batch, otherwise the credits will be issued in a new credit // batch. The new credit batch will be created under an existing project if a - // project with a matching reference id already exists within the scope of the - // credit class, otherwise a new project will be created. + // project with a matching reference id already exists, otherwise a new project + // will be created. BridgeReceive(ctx context.Context, in *MsgBridgeReceive, opts ...grpc.CallOption) (*MsgBridgeReceiveResponse, error) // AddCreditType is a governance method that allows the addition of new // credit types to the network. @@ -4104,7 +4094,8 @@ type MsgServer interface { // CreateOrUpdateApplicaton creates a new project credit class application, updates // the metadata for an existing one when changes have been requested, or withdraws // the application. When an application is withdrawn, its data will be deleted from - // state and the project may apply again to the same credit class in the future. + // state and the project may apply again to the same credit class in the future. Any + // new metadata will be passed to EventUpdateApplication including for withdrawals. // // Since Revision 3 CreateOrUpdateApplication(context.Context, *MsgCreateOrUpdateApplication) (*MsgCreateOrUpdateApplicationResponse, error) @@ -4199,8 +4190,8 @@ type MsgServer interface { // the scope of the provided credit class, the credits will be minted to the // existing credit batch, otherwise the credits will be issued in a new credit // batch. The new credit batch will be created under an existing project if a - // project with a matching reference id already exists within the scope of the - // credit class, otherwise a new project will be created. + // project with a matching reference id already exists, otherwise a new project + // will be created. BridgeReceive(context.Context, *MsgBridgeReceive) (*MsgBridgeReceiveResponse, error) // AddCreditType is a governance method that allows the addition of new // credit types to the network. @@ -5262,13 +5253,6 @@ func (m *MsgCreateUnregisteredProject) MarshalToSizedBuffer(dAtA []byte) (int, e i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a - } - if len(m.ReferenceId) > 0 { - i -= len(m.ReferenceId) - copy(dAtA[i:], m.ReferenceId) - i = encodeVarintTx(dAtA, i, uint64(len(m.ReferenceId))) - i-- dAtA[i] = 0x22 } if len(m.Jurisdiction) > 0 { @@ -7415,10 +7399,6 @@ func (m *MsgCreateUnregisteredProject) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.ReferenceId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } if m.Fee != nil { l = m.Fee.Size() n += 1 + l + sovTx(uint64(l)) @@ -9218,38 +9198,6 @@ func (m *MsgCreateUnregisteredProject) Unmarshal(dAtA []byte) error { m.Jurisdiction = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReferenceId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - 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 ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ReferenceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Fee", wireType) } diff --git a/x/ecocredit/base/utils.go b/x/ecocredit/base/utils.go index 899799c2fb..1fa25242d5 100644 --- a/x/ecocredit/base/utils.go +++ b/x/ecocredit/base/utils.go @@ -23,14 +23,10 @@ const ( var ( RegexCreditTypeAbbrev = `[A-Z]{1,3}` //nolint:gosec RegexClassID = fmt.Sprintf(`%s[0-9]{2,}`, RegexCreditTypeAbbrev) - RegexProjectID = fmt.Sprintf(`%s-[0-9]{3,}`, RegexClassID) - RegexBatchDenom = fmt.Sprintf(`%s-[0-9]{8}-[0-9]{8}-[0-9]{3,}`, RegexProjectID) RegexJurisdiction = `([A-Z]{2})(?:-([A-Z0-9]{1,3})(?: ([a-zA-Z0-9 \-]{1,64}))?)?` regexCreditTypeAbbrev = regexp.MustCompile(fmt.Sprintf(`^%s$`, RegexCreditTypeAbbrev)) regexClassID = regexp.MustCompile(fmt.Sprintf(`^%s$`, RegexClassID)) - regexProjectID = regexp.MustCompile(fmt.Sprintf(`^%s$`, RegexProjectID)) - regexBatchDenom = regexp.MustCompile(fmt.Sprintf(`^%s$`, RegexBatchDenom)) regexJurisdiction = regexp.MustCompile(fmt.Sprintf(`^%s$`, RegexJurisdiction)) ) @@ -51,27 +47,23 @@ func FormatClassID(creditTypeAbbreviation string, classSeqNo uint64) string { } // FormatProjectID formats the unique identifier for a new project, based on -// the credit class id and project sequence number. This format may evolve over -// time, but will maintain backwards compatibility. +// the project sequence number. This format may evolve over time. // // The current version has the format: -// - +// P // -// is the unique identifier of the credit class (see FormatClassID) -// is the sequence number of the project, padded to at least -// three digits -// -// e.g. C01-001 -func FormatProjectID(classID string, projectSeqNo uint64) string { - return fmt.Sprintf("%s-%03d", classID, projectSeqNo) +// e.g. P001 +func FormatProjectID(projectSeqNo uint64) string { + return fmt.Sprintf("P%03d", projectSeqNo) } // FormatBatchDenom formats the unique denomination for a credit batch. This // format may evolve over time, but will maintain backwards compatibility. // // The current version has the format: -// --- +// ---- // +// is the unique identifier of the credit class (see FormatClassID) // is the unique identifier of the project (see FormatProjectID) // is the start date of the credit batch with the format YYYYMMDD // is the end date of the credit batch with the format YYYYMMDD @@ -79,9 +71,12 @@ func FormatProjectID(classID string, projectSeqNo uint64) string { // three digits // // e.g. C01-001-20190101-20200101-001 -func FormatBatchDenom(projectID string, batchSeqNo uint64, startDate, endDate *time.Time) (string, error) { +func FormatBatchDenom(classId, projectID string, batchSeqNo uint64, startDate, endDate *time.Time) (string, error) { return fmt.Sprintf( - "%s-%s-%s-%03d", + "%s-%s-%s-%s-%03d", + + // Class ID string + classId, // Project ID string projectID, @@ -107,6 +102,9 @@ func ValidateCreditTypeAbbreviation(abbr string) error { if matches == nil { return ecocredit.ErrParseFailure.Wrapf("must be 1-3 uppercase alphabetic characters") } + if abbr == "P" { + return ecocredit.ErrParseFailure.Wrapf("P is reserved as the prefix for project IDs") + } return nil } @@ -129,10 +127,6 @@ func ValidateProjectID(projectID string) error { if projectID == "" { return ecocredit.ErrParseFailure.Wrap("empty string is not allowed") } - matches := regexProjectID.FindStringSubmatch(projectID) - if matches == nil { - return ecocredit.ErrParseFailure.Wrap("expected format -") - } return nil } @@ -142,12 +136,6 @@ func ValidateBatchDenom(denom string) error { if denom == "" { return ecocredit.ErrParseFailure.Wrap("empty string is not allowed") } - matches := regexBatchDenom.FindStringSubmatch(denom) - if matches == nil { - return ecocredit.ErrParseFailure.Wrap( - "expected format ---", - ) - } return nil } @@ -170,19 +158,6 @@ func ValidateJurisdiction(jurisdiction string) error { return nil } -// GetClassIDFromProjectID returns the credit class ID in a project ID. -func GetClassIDFromProjectID(projectID string) string { - var s strings.Builder - for _, r := range projectID { - if r != '-' { - s.WriteRune(r) - continue - } - break - } - return s.String() -} - // GetClassIDFromBatchDenom returns the credit class ID in a batch denom. func GetClassIDFromBatchDenom(denom string) string { var s strings.Builder @@ -196,23 +171,6 @@ func GetClassIDFromBatchDenom(denom string) string { return s.String() } -// GetProjectIDFromBatchDenom returns the credit project ID in a batch denom. -func GetProjectIDFromBatchDenom(denom string) string { - var s strings.Builder - c := 0 - for _, r := range denom { - if r == '-' { - c++ - } - if r != '-' || c != 2 { - s.WriteRune(r) - continue - } - break - } - return s.String() -} - // GetCreditTypeAbbrevFromClassID returns the credit type abbreviation in a credit class id func GetCreditTypeAbbrevFromClassID(classID string) string { var s strings.Builder diff --git a/x/ecocredit/base/utils_test.go b/x/ecocredit/base/utils_test.go index d3335978d8..d5dfd75526 100644 --- a/x/ecocredit/base/utils_test.go +++ b/x/ecocredit/base/utils_test.go @@ -12,12 +12,8 @@ func TestUtils(t *testing.T) { t.Run("TestFormatClassID", rapid.MakeCheck(testFormatClassID)) t.Run("TestInvalidClassID", rapid.MakeCheck(testInvalidClassID)) t.Run("TestFormatProjectID", rapid.MakeCheck(testFormatProjectID)) - t.Run("TestInvalidProjectID", rapid.MakeCheck(testInvalidProjectID)) t.Run("TestFormatBatchDenom", rapid.MakeCheck(testFormatBatchDenom)) - t.Run("TestInvalidBatchDenom", rapid.MakeCheck(testInvalidBatchDenom)) - t.Run("TestGetClassIDFromProjectID", rapid.MakeCheck(testGetClassIDFromProjectID)) t.Run("TestGetClassIDFromBatchDenom", rapid.MakeCheck(testGetClassIDFromBatchDenom)) - t.Run("TestGetProjectIDFromBatchDenom", rapid.MakeCheck(testGetProjectIDFromBatchDenom)) t.Run("GetCreditTypeAbbrevFromClassID", rapid.MakeCheck(testGetCreditTypeAbbrevFromClassID)) } @@ -39,12 +35,9 @@ func testInvalidClassID(t *rapid.T) { } func testFormatProjectID(t *rapid.T) { - creditTypeAbbrev := genCreditTypeAbbrev.Draw(t, "creditTypeAbbrev") - classSeq := rapid.Uint64().Draw(t, "classSeq") projectSeq := rapid.Uint64().Draw(t, "projectSeq") - classID := FormatClassID(creditTypeAbbrev, classSeq) - projectID := FormatProjectID(classID, projectSeq) + projectID := FormatProjectID(projectSeq) t.Log(projectID) @@ -52,11 +45,6 @@ func testFormatProjectID(t *rapid.T) { require.NoError(t, err) } -func testInvalidProjectID(t *rapid.T) { - projectID := genInvalidProjectID.Draw(t, "projectID") - require.Error(t, ValidateProjectID(projectID)) -} - func testFormatBatchDenom(t *rapid.T) { creditTypeAbbrev := genCreditTypeAbbrev.Draw(t, "creditTypeAbbrev") classSeq := rapid.Uint64().Draw(t, "classSeq") @@ -66,8 +54,8 @@ func testFormatBatchDenom(t *rapid.T) { endDate := genTime.Draw(t, "endDate") classID := FormatClassID(creditTypeAbbrev, classSeq) - projectID := FormatProjectID(classID, projectSeq) - denom, err := FormatBatchDenom(projectID, batchSeq, startDate, endDate) + projectID := FormatProjectID(projectSeq) + denom, err := FormatBatchDenom(classID, projectID, batchSeq, startDate, endDate) require.NoError(t, err) t.Log(denom) @@ -76,23 +64,6 @@ func testFormatBatchDenom(t *rapid.T) { require.NoError(t, err) } -func testInvalidBatchDenom(t *rapid.T) { - batchDenom := genInvalidBatchDenom.Draw(t, "batchDenom") - require.Error(t, ValidateBatchDenom(batchDenom)) -} - -func testGetClassIDFromProjectID(t *rapid.T) { - creditTypeAbbrev := genCreditTypeAbbrev.Draw(t, "creditTypeAbbrev") - classSeq := rapid.Uint64().Draw(t, "classSeq") - projectSeq := rapid.Uint64().Draw(t, "projectSeq") - - classID := FormatClassID(creditTypeAbbrev, classSeq) - projectID := FormatProjectID(classID, projectSeq) - - result := GetClassIDFromProjectID(projectID) - require.Equal(t, classID, result) -} - func testGetClassIDFromBatchDenom(t *rapid.T) { creditTypeAbbrev := genCreditTypeAbbrev.Draw(t, "creditTypeAbbrev") classSeq := rapid.Uint64().Draw(t, "classSeq") @@ -102,31 +73,14 @@ func testGetClassIDFromBatchDenom(t *rapid.T) { endDate := genTime.Draw(t, "endDate") classID := FormatClassID(creditTypeAbbrev, classSeq) - projectID := FormatProjectID(classID, projectSeq) - denom, err := FormatBatchDenom(projectID, batchSeq, startDate, endDate) + projectID := FormatProjectID(projectSeq) + denom, err := FormatBatchDenom(classID, projectID, batchSeq, startDate, endDate) require.NoError(t, err) result := GetClassIDFromBatchDenom(denom) require.Equal(t, classID, result) } -func testGetProjectIDFromBatchDenom(t *rapid.T) { - creditTypeAbbrev := genCreditTypeAbbrev.Draw(t, "creditTypeAbbrev") - classSeq := rapid.Uint64().Draw(t, "classSeq") - projectSeq := rapid.Uint64().Draw(t, "projectSeq") - batchSeq := rapid.Uint64().Draw(t, "batchSeq") - startDate := genTime.Draw(t, "startDate") - endDate := genTime.Draw(t, "endDate") - - classID := FormatClassID(creditTypeAbbrev, classSeq) - projectID := FormatProjectID(classID, projectSeq) - denom, err := FormatBatchDenom(projectID, batchSeq, startDate, endDate) - require.NoError(t, err) - - result := GetProjectIDFromBatchDenom(denom) - require.Equal(t, projectID, result) -} - func testGetCreditTypeAbbrevFromClassID(t *rapid.T) { creditTypeAbbrev := genCreditTypeAbbrev.Draw(t, "creditTypeAbbrev") classSeq := rapid.Uint64().Draw(t, "classSeq") @@ -146,19 +100,6 @@ var genInvalidClassID = rapid.OneOf( rapid.StringMatching(`[A-Z]{4,}[0-9]*`), ) -// genInvalidProjectID generates strings that don't conform to the project id format -var genInvalidProjectID = rapid.OneOf( - rapid.StringMatching(`[a-zA-Z]*`), - rapid.StringMatching(`[0-9]*`), - rapid.StringMatching(`[A-Z]{4,}[0-9]*`), -) - -// genInvalidBatchDenom generates strings that don't conform to the batch denom format -var genInvalidBatchDenom = rapid.OneOf( - genInvalidClassID, - rapid.StringMatching(`[A-Z]{1,3}[0-9]*-[a-zA-Z\-]*`), -) - // genTime generates time values up to the year ~9999 to avoid overflowing the // denomination format. var genTime = rapid.Custom(func(t *rapid.T) *time.Time { diff --git a/x/ecocredit/basket/keeper/msg_put_test.go b/x/ecocredit/basket/keeper/msg_put_test.go index 1bdcf68a31..89f3c560c3 100644 --- a/x/ecocredit/basket/keeper/msg_put_test.go +++ b/x/ecocredit/basket/keeper/msg_put_test.go @@ -222,19 +222,18 @@ func (s *putSuite) ACreditBatchWithDenom(a string) { classID := base.GetClassIDFromBatchDenom(a) creditTypeAbbrev := base.GetCreditTypeAbbrevFromClassID(classID) - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: classID, CreditTypeAbbrev: creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) err = s.baseStore.BatchTable().Insert(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: s.batchDenom, }) require.NoError(s.t, err) @@ -256,19 +255,18 @@ func (s *putSuite) AliceOwnsCredits() { classID := base.GetClassIDFromBatchDenom(s.batchDenom) creditTypeAbbrev := base.GetCreditTypeAbbrevFromClassID(classID) - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: classID, CreditTypeAbbrev: creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: s.batchDenom, }) require.NoError(s.t, err) @@ -285,19 +283,18 @@ func (s *putSuite) AliceOwnsCreditAmount(a string) { classID := base.GetClassIDFromBatchDenom(s.batchDenom) creditTypeAbbrev := base.GetCreditTypeAbbrevFromClassID(classID) - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: classID, CreditTypeAbbrev: creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: s.batchDenom, }) require.NoError(s.t, err) @@ -314,19 +311,18 @@ func (s *putSuite) AliceOwnsCreditsFromCreditBatch(a string) { classID := base.GetClassIDFromBatchDenom(a) creditTypeAbbrev := base.GetCreditTypeAbbrevFromClassID(classID) - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: classID, CreditTypeAbbrev: creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: a, }) require.NoError(s.t, err) @@ -343,19 +339,18 @@ func (s *putSuite) AliceOwnsCreditsWithStartDate(a string) { startDate, err := regentypes.ParseDate("start-date", a) require.NoError(s.t, err) - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: s.classID, CreditTypeAbbrev: s.creditTypeAbbrev, }) require.NoError(s.t, err) - pKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + pKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ ProjectKey: pKey, + ClassKey: clsKey, Denom: s.batchDenom, StartDate: timestamppb.New(startDate), }) diff --git a/x/ecocredit/basket/keeper/msg_take_test.go b/x/ecocredit/basket/keeper/msg_take_test.go index dd0457d858..e605990bca 100644 --- a/x/ecocredit/basket/keeper/msg_take_test.go +++ b/x/ecocredit/basket/keeper/msg_take_test.go @@ -418,19 +418,18 @@ func (s *takeSuite) addBasketClassAndBalance(basketID uint64, creditAmount strin classID := base.GetClassIDFromBatchDenom(s.batchDenom) creditTypeAbbrev := base.GetCreditTypeAbbrevFromClassID(classID) - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: classID, CreditTypeAbbrev: creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: s.batchDenom, }) require.NoError(s.t, err) diff --git a/x/ecocredit/basket/types/v1/features/msg_put.feature b/x/ecocredit/basket/types/v1/features/msg_put.feature index e9147060db..ff73a527ef 100644 --- a/x/ecocredit/basket/types/v1/features/msg_put.feature +++ b/x/ecocredit/basket/types/v1/features/msg_put.feature @@ -81,22 +81,6 @@ Feature: MsgPut When the message is validated Then expect the error "credits[0]: batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if a credit batch denom is not formatted - Given the message - """ - { - "owner": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw", - "basket_denom": "eco.uC.NCT", - "credits": [ - { - "batch_denom": "foo" - } - ] - } - """ - When the message is validated - Then expect the error "credits[0]: batch denom: expected format ---: parse error: invalid request" - Scenario: an error is returned if a credit amount is empty Given the message """ diff --git a/x/ecocredit/basket/types/v1/features/state_basket_balance.feature b/x/ecocredit/basket/types/v1/features/state_basket_balance.feature index a9e8498e21..28dc951f7f 100644 --- a/x/ecocredit/basket/types/v1/features/state_basket_balance.feature +++ b/x/ecocredit/basket/types/v1/features/state_basket_balance.feature @@ -31,17 +31,6 @@ Feature: BasketBalance When the basket balance is validated Then expect the error "batch denom: empty string is not allowed: parse error" - Scenario: an error is returned if batch denom is not formatted - Given the basket balance - """ - { - "basket_id": 1, - "batch_denom": "foo" - } - """ - When the basket balance is validated - Then expect the error "batch denom: expected format ---: parse error" - Scenario: an error is returned if balance is a negative decimal Given the basket balance """ diff --git a/x/ecocredit/client/testsuite/suite.go b/x/ecocredit/client/testsuite/suite.go index 57ce09ccea..a66b0e0df3 100644 --- a/x/ecocredit/client/testsuite/suite.go +++ b/x/ecocredit/client/testsuite/suite.go @@ -118,6 +118,7 @@ func (s *IntegrationTestSuite) SetupSuite() { s.batchDenom = s.createBatch(s.val.ClientCtx, &basetypes.MsgCreateBatch{ Issuer: s.addr1.String(), ProjectId: s.projectID, + ClassId: s.classID, Issuance: []*basetypes.BatchIssuance{ { Recipient: s.addr1.String(), diff --git a/x/ecocredit/client/testsuite/tx.go b/x/ecocredit/client/testsuite/tx.go index c2e452b7dd..fac7db8e13 100644 --- a/x/ecocredit/client/testsuite/tx.go +++ b/x/ecocredit/client/testsuite/tx.go @@ -212,6 +212,7 @@ func (s *IntegrationTestSuite) TestTxCreateBatchCmd() { bz, err := s.val.ClientCtx.Codec.MarshalJSON(&types.MsgCreateBatch{ Issuer: issuer, ProjectId: s.projectID, + ClassId: s.classID, Issuance: []*types.BatchIssuance{ { Recipient: recipient, diff --git a/x/ecocredit/client/tx.go b/x/ecocredit/client/tx.go index e66d416f84..5cae168a50 100644 --- a/x/ecocredit/client/tx.go +++ b/x/ecocredit/client/tx.go @@ -36,6 +36,8 @@ func TxCmd(name string) *cobra.Command { baseclient.TxUpdateProjectMetadataCmd(), baseclient.TxUpdateBatchMetadataCmd(), baseclient.TxBridgeCmd(), + baseclient.TxCreateOrUpdateApplicationCmd(), + baseclient.TxWithdrawApplicationCmd(), basketclient.TxCreateBasketCmd(), basketclient.TxPutInBasketCmd(), basketclient.TxTakeFromBasketCmd(), diff --git a/x/ecocredit/genesis/genesis.go b/x/ecocredit/genesis/genesis.go index 50eba85c88..fe777378b1 100644 --- a/x/ecocredit/genesis/genesis.go +++ b/x/ecocredit/genesis/genesis.go @@ -102,25 +102,6 @@ func ValidateGenesis(data json.RawMessage) error { } } - projectKeyToClassKey := make(map[uint64]uint64) // map of project key to class key - pItr, err := ss.ProjectTable().List(ormCtx, baseapi.ProjectPrimaryKey{}) - if err != nil { - return err - } - defer pItr.Close() - - for pItr.Next() { - project, err := pItr.Value() - if err != nil { - return err - } - - if _, exists := projectKeyToClassKey[project.Key]; exists { - continue - } - projectKeyToClassKey[project.Key] = project.ClassKey - } - batchIDToPrecision := make(map[uint64]uint32) // map of batchID to precision batchDenomToIDMap := make(map[string]uint64) // map of batchDenom to batchID bItr, err := ss.BatchTable().List(ormCtx, baseapi.BatchPrimaryKey{}) @@ -142,14 +123,12 @@ func ValidateGenesis(data json.RawMessage) error { continue } - class, err := ss.ClassTable().Get(ormCtx, projectKeyToClassKey[batch.ProjectKey]) + class, err := ss.ClassTable().Get(ormCtx, batch.ClassKey) if err != nil { return err } - if class.Key == projectKeyToClassKey[batch.ProjectKey] { - batchIDToPrecision[batch.Key] = abbrevToPrecision[class.CreditTypeAbbrev] - } + batchIDToPrecision[batch.Key] = abbrevToPrecision[class.CreditTypeAbbrev] } batchIDToCalSupply := make(map[uint64]math.Dec) // map of batchID to calculated supply @@ -276,12 +255,6 @@ func validateMsg(m proto.Message) error { return err } return msg.Validate() - case *baseapi.ProjectSequence: - msg := &basetypes.ProjectSequence{} - if err := ormutil.PulsarToGogoSlow(m, msg); err != nil { - return err - } - return msg.Validate() case *baseapi.BatchSequence: msg := &basetypes.BatchSequence{} if err := ormutil.PulsarToGogoSlow(m, msg); err != nil { diff --git a/x/ecocredit/genesis/genesis_test.go b/x/ecocredit/genesis/genesis_test.go index f4ef4ac14f..69ddc9a17a 100644 --- a/x/ecocredit/genesis/genesis_test.go +++ b/x/ecocredit/genesis/genesis_test.go @@ -43,6 +43,22 @@ func TestValidateGenesis(t *testing.T) { Precision: 6, })) + cls1 := &baseapi.Class{ + Id: "BIO001", + Admin: sdk.AccAddress("addr4"), + CreditTypeAbbrev: "BIO", + } + cls2 := &baseapi.Class{ + Id: "BIO002", + Admin: sdk.AccAddress("addr5"), + CreditTypeAbbrev: "BIO", + } + + clsKey1, err := ss.ClassTable().InsertReturningID(ormCtx, cls1) + require.NoError(t, err) + clsKey2, err := ss.ClassTable().InsertReturningID(ormCtx, cls2) + require.NoError(t, err) + require.NoError(t, ss.BatchBalanceTable().Insert(ormCtx, &baseapi.BatchBalance{ BatchKey: 1, @@ -55,7 +71,8 @@ func TestValidateGenesis(t *testing.T) { { Issuer: sdk.AccAddress("addr2"), ProjectKey: 1, - Denom: "BIO01-001-00000000-00000000-001", + ClassKey: clsKey1, + Denom: "BIO01-P001-00000000-00000000-001", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, IssuanceDate: ×tamppb.Timestamp{Seconds: 102}, @@ -63,7 +80,8 @@ func TestValidateGenesis(t *testing.T) { { Issuer: sdk.AccAddress("addr3"), ProjectKey: 1, - Denom: "BIO02-001-00000000-00000000-001", + ClassKey: clsKey2, + Denom: "BIO02-P001-00000000-00000000-001", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, IssuanceDate: ×tamppb.Timestamp{Seconds: 102}, @@ -80,34 +98,16 @@ func TestValidateGenesis(t *testing.T) { RetiredAmount: "9.997", })) - classes := []*baseapi.Class{ - { - Id: "BIO001", - Admin: sdk.AccAddress("addr4"), - CreditTypeAbbrev: "BIO", - }, - { - Id: "BIO002", - Admin: sdk.AccAddress("addr5"), - CreditTypeAbbrev: "BIO", - }, - } - for _, c := range classes { - require.NoError(t, ss.ClassTable().Insert(ormCtx, c)) - } - projects := []*baseapi.Project{ { - Id: "P01-001", + Id: "P001", Admin: sdk.AccAddress("addr6"), - ClassKey: 1, Jurisdiction: "AQ", Metadata: "meta", }, { - Id: "P02-001", + Id: "P002", Admin: sdk.AccAddress("addr7"), - ClassKey: 2, Jurisdiction: "AQ", Metadata: "meta", }, @@ -116,6 +116,22 @@ func TestValidateGenesis(t *testing.T) { require.NoError(t, ss.ProjectTable().Insert(ormCtx, p)) } + enrollments := []*baseapi.ProjectEnrollment{ + { + ProjectKey: 1, + ClassKey: 1, + Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }, + { + ProjectKey: 2, + ClassKey: 2, + Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }, + } + for _, e := range enrollments { + require.NoError(t, ss.ProjectEnrollmentTable().Insert(ormCtx, e)) + } + target := ormjson.NewRawMessageTarget() require.NoError(t, modDB.ExportJSON(ormCtx, target)) genesisJSON, err := target.JSON() @@ -212,7 +228,7 @@ func TestGenesisValidate(t *testing.T) { Precision: 6, })) denom := "C01-001-00000000-00000000-001" - key, err := ss.ClassTable().InsertReturningID(ctx, &baseapi.Class{ + cKey, err := ss.ClassTable().InsertReturningID(ctx, &baseapi.Class{ Id: "C01", Admin: addr1, CreditTypeAbbrev: "C", @@ -222,13 +238,21 @@ func TestGenesisValidate(t *testing.T) { pKey, err := ss.ProjectTable().InsertReturningID(ctx, &baseapi.Project{ Id: "P01-001", Admin: addr1, - ClassKey: key, Jurisdiction: "AQ", }) require.NoError(t, err) + + err = ss.ProjectEnrollmentTable().Insert(ctx, &baseapi.ProjectEnrollment{ + ProjectKey: pKey, + ClassKey: cKey, + Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + require.NoError(t, err) + bKey, err := ss.BatchTable().InsertReturningID(ctx, &baseapi.Batch{ Issuer: addr1, ProjectKey: pKey, + ClassKey: cKey, Denom: denom, StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -263,14 +287,21 @@ func TestGenesisValidate(t *testing.T) { pKey, err := ss.ProjectTable().InsertReturningID(ctx, &baseapi.Project{ Id: "P01-001", Admin: addr1, - ClassKey: cKey, Jurisdiction: "AQ", }) require.NoError(t, err) + err = ss.ProjectEnrollmentTable().Insert(ctx, &baseapi.ProjectEnrollment{ + ProjectKey: pKey, + ClassKey: cKey, + Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + require.NoError(t, err) + bKey, err := ss.BatchTable().InsertReturningID(ctx, &baseapi.Batch{ Issuer: addr1, ProjectKey: pKey, + ClassKey: cKey, Denom: denom, StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -311,13 +342,19 @@ func TestGenesisValidate(t *testing.T) { pKey, err := ss.ProjectTable().InsertReturningID(ctx, &baseapi.Project{ Id: "P01-001", Admin: addr1, - ClassKey: cKey, Jurisdiction: "AQ", }) require.NoError(t, err) + err = ss.ProjectEnrollmentTable().Insert(ctx, &baseapi.ProjectEnrollment{ + ProjectKey: pKey, + ClassKey: cKey, + Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + require.NoError(t, err) bKey, err := ss.BatchTable().InsertReturningID(ctx, &baseapi.Batch{ Issuer: addr1, ProjectKey: pKey, + ClassKey: cKey, Denom: "C01-001-00000000-00000000-001", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -377,20 +414,31 @@ func TestGenesisValidate(t *testing.T) { pKey, err := ss.ProjectTable().InsertReturningID(ctx, &baseapi.Project{ Id: "P01-001", Admin: addr1, - ClassKey: cKey, Jurisdiction: "AQ", }) require.NoError(t, err) + err = ss.ProjectEnrollmentTable().Insert(ctx, &baseapi.ProjectEnrollment{ + ProjectKey: pKey, + ClassKey: cKey, + Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + require.NoError(t, err) pKeyBIO, err := ss.ProjectTable().InsertReturningID(ctx, &baseapi.Project{ Id: "P02-001", Admin: addr1, - ClassKey: cKeyBIO, Jurisdiction: "AQ", }) require.NoError(t, err) + err = ss.ProjectEnrollmentTable().Insert(ctx, &baseapi.ProjectEnrollment{ + ProjectKey: pKeyBIO, + ClassKey: cKeyBIO, + Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + require.NoError(t, err) bKey, err := ss.BatchTable().InsertReturningID(ctx, &baseapi.Batch{ Issuer: addr1, ProjectKey: pKey, + ClassKey: cKey, Denom: "C01-001-00000000-00000000-001", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -400,6 +448,7 @@ func TestGenesisValidate(t *testing.T) { bKeyBIO, err := ss.BatchTable().InsertReturningID(ctx, &baseapi.Batch{ Issuer: addr1, ProjectKey: pKeyBIO, + ClassKey: cKeyBIO, Denom: "BIO01-001-00000000-00000000-001", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -409,6 +458,7 @@ func TestGenesisValidate(t *testing.T) { bKey2, err := ss.BatchTable().InsertReturningID(ctx, &baseapi.Batch{ Issuer: addr1, ProjectKey: pKey, + ClassKey: cKey, Denom: "C01-001-00000000-00000000-002", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -501,25 +551,6 @@ func TestGenesisValidate(t *testing.T) { true, "credit type abbrev: empty string is not allowed: parse error", }, - { - "valid: project sequence", - func(ctx context.Context, ss baseapi.StateStore) { - require.NoError(t, ss.ProjectSequenceTable().Insert(ctx, &baseapi.ProjectSequence{ - ClassKey: 1, - NextSequence: 1, - })) - }, - false, - "", - }, - { - "invalid: project sequence", - func(ctx context.Context, ss baseapi.StateStore) { - require.NoError(t, ss.ProjectSequenceTable().Insert(ctx, &baseapi.ProjectSequence{})) - }, - true, - "class key cannot be zero: parse error", - }, { "valid: batch sequence", func(ctx context.Context, ss baseapi.StateStore) { @@ -834,6 +865,13 @@ func TestValidateGenesisWithBasketBalance(t *testing.T) { bsktStore, err := basketapi.NewStateStore(modDB) require.NoError(t, err) + require.NoError(t, ss.CreditTypeTable().Insert(ormCtx, &baseapi.CreditType{ + Abbreviation: "C", + Name: "carbon", + Unit: "tons", + Precision: 6, + })) + require.NoError(t, ss.CreditTypeTable().Insert(ormCtx, &baseapi.CreditType{ Abbreviation: "BIO", Name: "biodiversity", @@ -841,27 +879,25 @@ func TestValidateGenesisWithBasketBalance(t *testing.T) { Precision: 6, })) - require.NoError(t, ss.BatchBalanceTable().Insert(ormCtx, - &baseapi.BatchBalance{ - BatchKey: 1, - Address: sdk.AccAddress("addr1"), - TradableAmount: "90.003", - RetiredAmount: "9.997", - })) + carbonClsKey, err := ss.ClassTable().InsertReturningID(ormCtx, &baseapi.Class{ + Id: "C001", + Admin: sdk.AccAddress("addr4"), + CreditTypeAbbrev: "C", + }) + require.NoError(t, err) - require.NoError(t, ss.BatchBalanceTable().Insert(ormCtx, - &baseapi.BatchBalance{ - BatchKey: 2, - Address: sdk.AccAddress("addr1"), - TradableAmount: "1.234", - EscrowedAmount: "1.234", - RetiredAmount: "0", - })) + bioClsKey, err := ss.ClassTable().InsertReturningID(ormCtx, &baseapi.Class{ + Id: "BIO001", + Admin: sdk.AccAddress("addr4"), + CreditTypeAbbrev: "BIO", + }) + require.NoError(t, err) batches := []*baseapi.Batch{ { Issuer: sdk.AccAddress("addr2"), ProjectKey: 1, + ClassKey: carbonClsKey, Denom: "C01-001-20200101-20210101-001", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -870,6 +906,7 @@ func TestValidateGenesisWithBasketBalance(t *testing.T) { { Issuer: sdk.AccAddress("addr3"), ProjectKey: 1, + ClassKey: bioClsKey, Denom: "BIO02-001-20200101-20210101-001", StartDate: ×tamppb.Timestamp{Seconds: 100}, EndDate: ×tamppb.Timestamp{Seconds: 101}, @@ -880,6 +917,23 @@ func TestValidateGenesisWithBasketBalance(t *testing.T) { require.NoError(t, ss.BatchTable().Insert(ormCtx, b)) } + require.NoError(t, ss.BatchBalanceTable().Insert(ormCtx, + &baseapi.BatchBalance{ + BatchKey: 1, + Address: sdk.AccAddress("addr1"), + TradableAmount: "90.003", + RetiredAmount: "9.997", + })) + + require.NoError(t, ss.BatchBalanceTable().Insert(ormCtx, + &baseapi.BatchBalance{ + BatchKey: 2, + Address: sdk.AccAddress("addr1"), + TradableAmount: "1.234", + EscrowedAmount: "1.234", + RetiredAmount: "0", + })) + require.NoError(t, ss.BatchSupplyTable().Insert(ormCtx, &baseapi.BatchSupply{ BatchKey: 1, @@ -896,17 +950,9 @@ func TestValidateGenesisWithBasketBalance(t *testing.T) { }), ) - class := baseapi.Class{ - Id: "BIO001", - Admin: sdk.AccAddress("addr4"), - CreditTypeAbbrev: "BIO", - } - require.NoError(t, ss.ClassTable().Insert(ormCtx, &class)) - project := baseapi.Project{ Id: "P01-001", Admin: sdk.AccAddress("addr6"), - ClassKey: 1, Jurisdiction: "AQ", Metadata: "meta", } diff --git a/x/ecocredit/go.mod b/x/ecocredit/go.mod index f1d9ed7257..9916b3188e 100644 --- a/x/ecocredit/go.mod +++ b/x/ecocredit/go.mod @@ -5,6 +5,7 @@ go 1.21 require ( cosmossdk.io/errors v1.0.0 cosmossdk.io/math v1.2.0 + github.com/cockroachdb/apd/v3 v3.2.1 github.com/cosmos/cosmos-sdk v0.46.12 github.com/cosmos/cosmos-sdk/api v0.1.0 github.com/cosmos/cosmos-sdk/orm v1.0.0-alpha.12 @@ -14,7 +15,7 @@ require ( github.com/golang/protobuf v1.5.3 github.com/google/go-cmp v0.6.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/regen-network/gocuke v1.1.0 + github.com/regen-network/gocuke v1.1.1 github.com/regen-network/regen-ledger/api/v2 v2.0.0 github.com/regen-network/regen-ledger/types/v2 v2.0.0 github.com/spf13/cobra v1.8.0 @@ -52,7 +53,6 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect - github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect @@ -64,10 +64,9 @@ require ( github.com/cosmos/iavl v0.19.6 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect - github.com/cucumber/common/messages/go/v19 v19.1.2 // indirect - github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect - github.com/cucumber/messages/go/v21 v21.0.1 // indirect - github.com/cucumber/tag-expressions/go/v5 v5.0.6 // indirect + github.com/cucumber/gherkin/go/v27 v27.0.0 // indirect + github.com/cucumber/messages/go/v22 v22.0.0 // indirect + github.com/cucumber/tag-expressions/go/v6 v6.1.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect diff --git a/x/ecocredit/go.sum b/x/ecocredit/go.sum index a2070b763d..686fcc3fe3 100644 --- a/x/ecocredit/go.sum +++ b/x/ecocredit/go.sum @@ -399,14 +399,12 @@ github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6V github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/common/messages/go/v19 v19.1.2 h1:8/ZkW9rj3KQo/regmI8kcy48tk57m427Olb7Y0lXcN4= -github.com/cucumber/common/messages/go/v19 v19.1.2/go.mod h1:0KLDvMVmmkEZcWUSKxFHSUSLS1gjujBbPN0p41IwwJ4= -github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= -github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= -github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= -github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= -github.com/cucumber/tag-expressions/go/v5 v5.0.6 h1:F0mqsu69cG/3MTTZqy+PlaPcU/MMl936OJjxKgdFgWs= -github.com/cucumber/tag-expressions/go/v5 v5.0.6/go.mod h1:/sHRc0Vt+pPjgQdNZjH8W2cnmb+tiVYp19VESzpGQsw= +github.com/cucumber/gherkin/go/v27 v27.0.0 h1:waJh5eeq7rrKn5Gf3/FI4G34ypduPRaV8e370dnupDI= +github.com/cucumber/gherkin/go/v27 v27.0.0/go.mod h1:2JxwYskO0sO4kumc/Nv1g6bMncT5w0lShuKZnmUIhhk= +github.com/cucumber/messages/go/v22 v22.0.0 h1:hk3ITpEWQ+KWDe619zYcqtaLOfcu9jgClSeps3DlNWI= +github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= +github.com/cucumber/tag-expressions/go/v6 v6.1.0 h1:YOhnlISh/lyPZrLojFbJVzocv7TGhzOhB9aULN8A7Sg= +github.com/cucumber/tag-expressions/go/v6 v6.1.0/go.mod h1:6scGHUy3RLnbNq8un7XNoopF2qR/0RMgqolQH/TkycY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -547,7 +545,6 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= @@ -1038,8 +1035,8 @@ github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzy github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/cosmos-sdk v0.46.13-regen-1 h1:sCwCgBtvrg7P2SbjK29a+sxUQW6Bh+/AMqlT0ezxHpc= github.com/regen-network/cosmos-sdk v0.46.13-regen-1/go.mod h1:EfY521ATNEla8eJ6oJuZBdgP5+p360s7InnRqX+TWdM= -github.com/regen-network/gocuke v1.1.0 h1:gxlkRTfpR9gJ0mwqQZIpoXHZGx+KPshKQpKE0jtUH5s= -github.com/regen-network/gocuke v1.1.0/go.mod h1:nVBO9DEnZNUB/GjmJgAIojKxcEu9a0EZwry0qKW24Mk= +github.com/regen-network/gocuke v1.1.1 h1:13D3n5xLbpzA/J2ELHC9jXYq0+XyEr64A3ehjvfmBbE= +github.com/regen-network/gocuke v1.1.1/go.mod h1:Nl9EbhLmTzdLqb52fr/Fvf8LcoVuTjjf8FlLmXz1zHo= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= @@ -1119,7 +1116,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= diff --git a/x/ecocredit/marketplace/keeper/keeper_test.go b/x/ecocredit/marketplace/keeper/keeper_test.go index 30658821f9..1090c21c8d 100644 --- a/x/ecocredit/marketplace/keeper/keeper_test.go +++ b/x/ecocredit/marketplace/keeper/keeper_test.go @@ -47,6 +47,7 @@ type baseSuite struct { bankKeeper *mocks.MockBankKeeper storeKey *storetypes.KVStoreKey sdkCtx sdk.Context + classId uint64 } func setupBase(t gocuke.TestingT, numAddresses int) *baseSuite { @@ -116,14 +117,17 @@ func (s *baseSuite) testSellSetup(batchDenom, bankDenom, displayDenom, classID s Precision: 6, })) - assert.NilError(s.t, s.baseStore.ClassTable().Insert(s.ctx, &baseapi.Class{ + var err error + s.classId, err = s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: classID, Admin: s.addrs[0], Metadata: "", CreditTypeAbbrev: creditType.Abbreviation, - })) + }) + assert.NilError(s.t, err) assert.NilError(s.t, s.baseStore.BatchTable().Insert(s.ctx, &baseapi.Batch{ ProjectKey: 1, + ClassKey: s.classId, Denom: batchDenom, Metadata: "", StartDate: start, diff --git a/x/ecocredit/marketplace/keeper/msg_buy_direct.go b/x/ecocredit/marketplace/keeper/msg_buy_direct.go index 5ba4b1d3e8..3e5fb306dc 100644 --- a/x/ecocredit/marketplace/keeper/msg_buy_direct.go +++ b/x/ecocredit/marketplace/keeper/msg_buy_direct.go @@ -55,7 +55,7 @@ func (k Keeper) BuyDirect(ctx context.Context, req *types.MsgBuyDirect) (*types. if err != nil { return nil, err } - ct, err := utils.GetCreditTypeFromBatchDenom(ctx, k.baseStore, batch.Denom) + ct, err := utils.GetCreditTypeFromBatchDenom(ctx, k.baseStore, batch) if err != nil { return nil, err } diff --git a/x/ecocredit/marketplace/keeper/msg_buy_direct_test.go b/x/ecocredit/marketplace/keeper/msg_buy_direct_test.go index 53014eea70..27779db262 100644 --- a/x/ecocredit/marketplace/keeper/msg_buy_direct_test.go +++ b/x/ecocredit/marketplace/keeper/msg_buy_direct_test.go @@ -13,11 +13,12 @@ import ( "github.com/google/go-cmp/cmp" "github.com/regen-network/gocuke" "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" protoreflect "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/testing/protocmp" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/orm/types/ormerrors" sdk "github.com/cosmos/cosmos-sdk/types" @@ -629,14 +630,15 @@ func (s *buyDirectSuite) createSellOrders(count int) { totalQuantity = t.String() } - err := s.baseStore.ClassTable().Insert(s.ctx, &baseapi.Class{ + clsId, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: s.classID, CreditTypeAbbrev: s.creditTypeAbbrev, }) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ - Denom: s.batchDenom, + Denom: s.batchDenom, + ClassKey: clsId, }) require.NoError(s.t, err) diff --git a/x/ecocredit/marketplace/keeper/msg_cancel_sell_order_test.go b/x/ecocredit/marketplace/keeper/msg_cancel_sell_order_test.go index a139c339bd..054c1001b4 100644 --- a/x/ecocredit/marketplace/keeper/msg_cancel_sell_order_test.go +++ b/x/ecocredit/marketplace/keeper/msg_cancel_sell_order_test.go @@ -151,14 +151,15 @@ func (s *cancelSellOrder) ExpectEventWithProperties(a gocuke.DocString) { } func (s *cancelSellOrder) sellOrderSetup() { - err := s.baseStore.ClassTable().Insert(s.ctx, &baseapi.Class{ + clsId, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: s.classID, CreditTypeAbbrev: s.creditTypeAbbrev, }) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ - Denom: s.batchDenom, + Denom: s.batchDenom, + ClassKey: clsId, }) require.NoError(s.t, err) diff --git a/x/ecocredit/marketplace/keeper/msg_gov_send_from_fee_pool_test.go b/x/ecocredit/marketplace/keeper/msg_gov_send_from_fee_pool_test.go index 6ca51c2733..c3f012b5d8 100644 --- a/x/ecocredit/marketplace/keeper/msg_gov_send_from_fee_pool_test.go +++ b/x/ecocredit/marketplace/keeper/msg_gov_send_from_fee_pool_test.go @@ -3,12 +3,13 @@ package keeper import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/golang/mock/gomock" "github.com/regen-network/gocuke" "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + types "github.com/regen-network/regen-ledger/x/ecocredit/v3/marketplace/types/v1" ) diff --git a/x/ecocredit/marketplace/keeper/msg_sell.go b/x/ecocredit/marketplace/keeper/msg_sell.go index a48bbf2d5a..e358ebac9d 100644 --- a/x/ecocredit/marketplace/keeper/msg_sell.go +++ b/x/ecocredit/marketplace/keeper/msg_sell.go @@ -40,7 +40,7 @@ func (k Keeper) Sell(ctx context.Context, req *types.MsgSell) (*types.MsgSellRes ) } - creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.baseStore, batch.Denom) + creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.baseStore, batch) if err != nil { return nil, err } diff --git a/x/ecocredit/marketplace/keeper/msg_sell_test.go b/x/ecocredit/marketplace/keeper/msg_sell_test.go index 1265b94ac6..23a466afd9 100644 --- a/x/ecocredit/marketplace/keeper/msg_sell_test.go +++ b/x/ecocredit/marketplace/keeper/msg_sell_test.go @@ -110,19 +110,18 @@ func (s *sellSuite) ACreditBatchWithBatchDenom(a string) { classID := base.GetClassIDFromBatchDenom(a) creditTypeAbbrev := base.GetCreditTypeAbbrevFromClassID(classID) - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: classID, CreditTypeAbbrev: creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) err = s.baseStore.BatchTable().Insert(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: a, }) require.NoError(s.t, err) @@ -421,19 +420,18 @@ func (s *sellSuite) ExpectEventWithProperties(a gocuke.DocString) { } func (s *sellSuite) aliceTradableBatchBalance() { - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: s.classID, CreditTypeAbbrev: s.creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: s.batchDenom, }) require.NoError(s.t, err) diff --git a/x/ecocredit/marketplace/keeper/msg_update_sell_orders.go b/x/ecocredit/marketplace/keeper/msg_update_sell_orders.go index e9f8dd451c..05b95cfee0 100644 --- a/x/ecocredit/marketplace/keeper/msg_update_sell_orders.go +++ b/x/ecocredit/marketplace/keeper/msg_update_sell_orders.go @@ -178,7 +178,7 @@ func (k Keeper) getCreditTypeFromBatchKey(ctx context.Context, key uint64) (*bas if err != nil { return nil, err } - creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.baseStore, batch.Denom) + creditType, err := utils.GetCreditTypeFromBatchDenom(ctx, k.baseStore, batch) if err != nil { return nil, err } diff --git a/x/ecocredit/marketplace/keeper/msg_update_sell_orders_test.go b/x/ecocredit/marketplace/keeper/msg_update_sell_orders_test.go index 0490e96f8f..09c736ed18 100644 --- a/x/ecocredit/marketplace/keeper/msg_update_sell_orders_test.go +++ b/x/ecocredit/marketplace/keeper/msg_update_sell_orders_test.go @@ -432,14 +432,15 @@ func (s *updateSellOrdersSuite) sellOrderSetup(count int) { totalQuantity = t.String() } - err := s.baseStore.ClassTable().Insert(s.ctx, &baseapi.Class{ + clsId, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: s.classID, CreditTypeAbbrev: s.creditTypeAbbrev, }) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ - Denom: s.batchDenom, + Denom: s.batchDenom, + ClassKey: clsId, }) require.NoError(s.t, err) @@ -489,19 +490,18 @@ func (s *updateSellOrdersSuite) sellOrderSetup(count int) { func (s *updateSellOrdersSuite) aliceBatchBalance() { batch, err := s.baseStore.BatchTable().GetByDenom(s.ctx, s.batchDenom) if err == ormerrors.NotFound { - classKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ + clsKey, err := s.baseStore.ClassTable().InsertReturningID(s.ctx, &baseapi.Class{ Id: s.classID, CreditTypeAbbrev: s.creditTypeAbbrev, }) require.NoError(s.t, err) - projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{ - ClassKey: classKey, - }) + projectKey, err := s.baseStore.ProjectTable().InsertReturningID(s.ctx, &baseapi.Project{}) require.NoError(s.t, err) batchKey, err := s.baseStore.BatchTable().InsertReturningID(s.ctx, &baseapi.Batch{ ProjectKey: projectKey, + ClassKey: clsKey, Denom: s.batchDenom, }) require.NoError(s.t, err) diff --git a/x/ecocredit/marketplace/keeper/query_sell_orders_by_batch_test.go b/x/ecocredit/marketplace/keeper/query_sell_orders_by_batch_test.go index f1cbdd4551..fbfb3293b0 100644 --- a/x/ecocredit/marketplace/keeper/query_sell_orders_by_batch_test.go +++ b/x/ecocredit/marketplace/keeper/query_sell_orders_by_batch_test.go @@ -21,6 +21,7 @@ func TestSellOrdersByBatch(t *testing.T) { otherDenom := "C01-19990101-20290101-001" assert.NilError(t, s.baseStore.BatchTable().Insert(s.ctx, &ecocreditApi.Batch{ ProjectKey: 1, + ClassKey: s.classId, Denom: otherDenom, Metadata: "", StartDate: nil, diff --git a/x/ecocredit/marketplace/types/v1/features/msg_sell.feature b/x/ecocredit/marketplace/types/v1/features/msg_sell.feature index f5377cd05c..0f28e8f37d 100644 --- a/x/ecocredit/marketplace/types/v1/features/msg_sell.feature +++ b/x/ecocredit/marketplace/types/v1/features/msg_sell.feature @@ -131,21 +131,6 @@ Feature: MsgSell When the message is validated Then expect the error "orders[0]: batch denom: empty string is not allowed: parse error: invalid request" - Scenario: an error is returned if order batch denom is not formatted - Given the message - """ - { - "seller": "regen1elq7ys34gpkj3jyvqee0h6yk4h9wsfxmgqelsw", - "orders": [ - { - "batch_denom": "foo" - } - ] - } - """ - When the message is validated - Then expect the error "orders[0]: batch denom: expected format ---: parse error: invalid request" - Scenario: an error is returned if order quantity is empty Given the message """ diff --git a/x/ecocredit/marketplace/types/v1/msg_gov_send_from_fee_pool_test.go b/x/ecocredit/marketplace/types/v1/msg_gov_send_from_fee_pool_test.go index 8faff2dd3a..14e25165e7 100644 --- a/x/ecocredit/marketplace/types/v1/msg_gov_send_from_fee_pool_test.go +++ b/x/ecocredit/marketplace/types/v1/msg_gov_send_from_fee_pool_test.go @@ -3,9 +3,10 @@ package v1 import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/regen-network/gocuke" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) type govSendFromFeePool struct { diff --git a/x/ecocredit/migrations/v5/state.go b/x/ecocredit/migrations/v5/state.go new file mode 100644 index 0000000000..a78f3a08a4 --- /dev/null +++ b/x/ecocredit/migrations/v5/state.go @@ -0,0 +1,86 @@ +package v5 + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + ecocreditv1 "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" +) + +// MigrateState performs in-place store migrations from ConsensusVersion 4 to 5. +func MigrateState(sdkCtx sdk.Context, baseStore ecocreditv1.StateStore) error { + // collect all the classes associated with batches by looking up the class key from the project + batchIt, err := baseStore.BatchTable().List(sdkCtx, ecocreditv1.BatchPrimaryKey{}) + if err != nil { + return err + } + + batchClasses := map[uint64]uint64{} + for batchIt.Next() { + batch, err := batchIt.Value() + if err != nil { + return err + } + + if batch.ClassKey != 0 { + return fmt.Errorf("unexpected state, expected batch class key to be 0 before migration, got %d", batch.ClassKey) + } + + proj, err := baseStore.ProjectTable().Get(sdkCtx, batch.ProjectKey) + if err != nil { + return err + } + + batchClasses[batch.Key] = proj.ClassKey //nolint:staticcheck + } + batchIt.Close() + + // set class keys on batches + for batchKey, classKey := range batchClasses { + batch, err := baseStore.BatchTable().Get(sdkCtx, batchKey) + if err != nil { + return err + } + + batch.ClassKey = classKey + if err := baseStore.BatchTable().Save(sdkCtx, batch); err != nil { + return err + } + } + + // collect all the classes associated with projects + projectIt, err := baseStore.ProjectTable().List(sdkCtx, ecocreditv1.ProjectPrimaryKey{}) + if err != nil { + return err + } + + projectClasses := map[uint64]uint64{} + for projectIt.Next() { + proj, err := projectIt.Value() + if err != nil { + return err + } + + if proj.ClassKey == 0 { //nolint:staticcheck + return fmt.Errorf("unexpected state, expected project class key to be non-zero before migration, got %d", proj.ClassKey) //nolint:staticcheck + } + + projectClasses[proj.Key] = proj.ClassKey //nolint:staticcheck + } + projectIt.Close() + + // create enrollment entries for all project class relationships + for projectKey, classKey := range projectClasses { + err = baseStore.ProjectEnrollmentTable().Insert(sdkCtx, &ecocreditv1.ProjectEnrollment{ + ProjectKey: projectKey, + ClassKey: classKey, + Status: ecocreditv1.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED, + }) + if err != nil { + return err + } + } + + return nil +} diff --git a/x/ecocredit/migrations/v5/state_test.go b/x/ecocredit/migrations/v5/state_test.go new file mode 100644 index 0000000000..71fd542d5b --- /dev/null +++ b/x/ecocredit/migrations/v5/state_test.go @@ -0,0 +1,144 @@ +package v5 + +import ( + "testing" + + "github.com/stretchr/testify/require" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/orm/model/ormdb" + "github.com/cosmos/cosmos-sdk/orm/model/ormtable" + "github.com/cosmos/cosmos-sdk/orm/testing/ormtest" + "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + ecocreditv1 "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" + "github.com/regen-network/regen-ledger/x/ecocredit/v3" +) + +func TestMigrate(t *testing.T) { + ctx, state := setup(t) + + // create some test classes + clsKey1, err := state.ClassTable().InsertReturningID(ctx, &ecocreditv1.Class{ + Id: "C01", + }) + require.NoError(t, err) + + clsKey2, err := state.ClassTable().InsertReturningID(ctx, &ecocreditv1.Class{ + Id: "BIO01", + }) + require.NoError(t, err) + // create some test projects + projKey1, err := state.ProjectTable().InsertReturningID(ctx, &ecocreditv1.Project{ + Id: "C01-001", + ClassKey: clsKey1, + }) + require.NoError(t, err) + + projKey2, err := state.ProjectTable().InsertReturningID(ctx, &ecocreditv1.Project{ + Id: "C01-002", + ClassKey: clsKey1, + }) + require.NoError(t, err) + + projKey3, err := state.ProjectTable().InsertReturningID(ctx, &ecocreditv1.Project{ + Id: "BIO01-001", + ClassKey: clsKey2, + }) + require.NoError(t, err) + // create some test batches + batchKey1, err := state.BatchTable().InsertReturningID(ctx, &ecocreditv1.Batch{ + Denom: "C01-001-001", + ProjectKey: projKey1, + }) + require.NoError(t, err) + + batchKey2, err := state.BatchTable().InsertReturningID(ctx, &ecocreditv1.Batch{ + Denom: "C01-001-002", + ProjectKey: projKey1, + }) + require.NoError(t, err) + + batchKey3, err := state.BatchTable().InsertReturningID(ctx, &ecocreditv1.Batch{ + Denom: "C01-002-001", + ProjectKey: projKey2, + }) + require.NoError(t, err) + + batchKey4, err := state.BatchTable().InsertReturningID(ctx, &ecocreditv1.Batch{ + Denom: "BIO01-001-001", + ProjectKey: projKey3, + }) + require.NoError(t, err) + + batchKey5, err := state.BatchTable().InsertReturningID(ctx, &ecocreditv1.Batch{ + Denom: "BIO01-001-002", + ProjectKey: projKey3, + }) + require.NoError(t, err) + + // run the migration + require.NoError(t, MigrateState(ctx, state)) + + // check that the class keys on the batches are set correctly + batch1, err := state.BatchTable().Get(ctx, batchKey1) + require.NoError(t, err) + require.Equal(t, clsKey1, batch1.ClassKey) + + batch2, err := state.BatchTable().Get(ctx, batchKey2) + require.NoError(t, err) + require.Equal(t, clsKey1, batch2.ClassKey) + + batch3, err := state.BatchTable().Get(ctx, batchKey3) + require.NoError(t, err) + require.Equal(t, clsKey1, batch3.ClassKey) + + batch4, err := state.BatchTable().Get(ctx, batchKey4) + require.NoError(t, err) + require.Equal(t, clsKey2, batch4.ClassKey) + + batch5, err := state.BatchTable().Get(ctx, batchKey5) + require.NoError(t, err) + require.Equal(t, clsKey2, batch5.ClassKey) + + // check that enrollment entries are created for all project class relationships + enrollment1, err := state.ProjectEnrollmentTable().Get(ctx, projKey1, clsKey1) + require.NoError(t, err) + require.Equal(t, projKey1, enrollment1.ProjectKey) + require.Equal(t, clsKey1, enrollment1.ClassKey) + + enrollment2, err := state.ProjectEnrollmentTable().Get(ctx, projKey2, clsKey1) + require.NoError(t, err) + require.Equal(t, projKey2, enrollment2.ProjectKey) + require.Equal(t, clsKey1, enrollment2.ClassKey) + + enrollment3, err := state.ProjectEnrollmentTable().Get(ctx, projKey3, clsKey2) + require.NoError(t, err) + require.Equal(t, projKey3, enrollment3.ProjectKey) + +} + +func setup(t *testing.T) (sdk.Context, ecocreditv1.StateStore) { + ecocreditKey := sdk.NewKVStoreKey("ecocredit") + + db := dbm.NewMemDB() + cms := store.NewCommitMultiStore(db) + cms.MountStoreWithDB(ecocreditKey, storetypes.StoreTypeIAVL, db) + + require.NoError(t, cms.LoadLatestVersion()) + + ormCtx := ormtable.WrapContextDefault(ormtest.NewMemoryBackend()) + sdkCtx := sdk.NewContext(cms, tmproto.Header{}, false, log.NewNopLogger()).WithContext(ormCtx) + + modDB, err := ormdb.NewModuleDB(&ecocredit.ModuleSchema, ormdb.ModuleDBOptions{}) + require.NoError(t, err) + + baseStore, err := ecocreditv1.NewStateStore(modDB) + require.NoError(t, err) + + return sdkCtx, baseStore +} diff --git a/x/ecocredit/module/module.go b/x/ecocredit/module/module.go index 0d3bc0b7b5..91f57dfec5 100644 --- a/x/ecocredit/module/module.go +++ b/x/ecocredit/module/module.go @@ -139,6 +139,10 @@ func (m *Module) RegisterServices(cfg module.Configurator) { panic(err) } + if err := cfg.RegisterMigration(ecocredit.ModuleName, 4, migrator.Migrate4to5); err != nil { + panic(err) + } + m.Keeper = svr } diff --git a/x/ecocredit/server/migrations.go b/x/ecocredit/server/migrations.go index 6c11719764..59e953ffb8 100644 --- a/x/ecocredit/server/migrations.go +++ b/x/ecocredit/server/migrations.go @@ -7,6 +7,7 @@ import ( ecocreditv1 "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" v3 "github.com/regen-network/regen-ledger/x/ecocredit/v3/migrations/v3" v4 "github.com/regen-network/regen-ledger/x/ecocredit/v3/migrations/v4" + v5 "github.com/regen-network/regen-ledger/x/ecocredit/v3/migrations/v5" ) // Migrator is a struct for handling in-place store migrations. @@ -45,3 +46,9 @@ func (m Migrator) Migrate3to4(ctx sdk.Context) error { baseStore, basketStore, _ := m.keeper.GetStateStores() return v4.MigrateState(ctx, baseStore, basketStore) } + +// Migrate4to5 migrates from version 4 to 5. +func (m Migrator) Migrate4to5(ctx sdk.Context) error { + baseStore, _, _ := m.keeper.GetStateStores() + return v5.MigrateState(ctx, baseStore) +} diff --git a/x/ecocredit/server/tests/features/bridge.feature b/x/ecocredit/server/tests/features/bridge.feature index 2bf3d10829..e8524179e4 100644 --- a/x/ecocredit/server/tests/features/bridge.feature +++ b/x/ecocredit/server/tests/features/bridge.feature @@ -65,8 +65,8 @@ Feature: Bridge Integration And expect event bridge receive with values """ { - "project_id": "C01-001", - "batch_denom": "C01-001-20200101-20210101-001", + "project_id": "P001", + "batch_denom": "C01-P001-20200101-20210101-001", "amount": "100", "origin_tx": { "id": "0x0000000000000000000000000000000000000000000000000000000000000001", @@ -79,7 +79,7 @@ Feature: Bridge Integration And expect project with properties """ { - "id": "C01-001", + "id": "P001", "metadata": "regen:13toVfvC2YxrrfSXWB5h2BGHiXZURsKxWUz72uDRDSPMCrYPguGUXSC.rdf", "jurisdiction": "US-WA", "reference_id": "VCS-001" @@ -89,14 +89,14 @@ Feature: Bridge Integration And expect credit batch with properties """ { - "denom": "C01-001-20200101-20210101-001", + "denom": "C01-P001-20200101-20210101-001", "metadata": "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf", "start_date": "2020-01-01T00:00:00Z", "end_date": "2021-01-01T00:00:00Z", "open": true } """ - And expect batch supply with batch denom "C01-001-20200101-20210101-001" + And expect batch supply with batch denom "C01-P001-20200101-20210101-001" """ { "tradable_amount": "100", @@ -104,7 +104,7 @@ Feature: Bridge Integration "cancelled_amount": "0" } """ - And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-001-20200101-20210101-001" + And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-P001-20200101-20210101-001" """ { "tradable_amount": "100", @@ -174,8 +174,8 @@ Feature: Bridge Integration And expect event bridge receive with values """ { - "project_id": "C01-001", - "batch_denom": "C01-001-20200101-20210101-001", + "project_id": "P001", + "batch_denom": "C01-P001-20200101-20210101-001", "amount": "100", "origin_tx": { "id": "0x0000000000000000000000000000000000000000000000000000000000000002", @@ -186,7 +186,7 @@ Feature: Bridge Integration """ And expect total projects "1" And expect total credit batches "1" - And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-001-20200101-20210101-001" + And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-P001-20200101-20210101-001" """ { "tradable_amount": "200", @@ -225,8 +225,8 @@ Feature: Bridge Integration And expect event bridge receive with values """ { - "project_id": "C01-001", - "batch_denom": "C01-001-20200101-20210101-002", + "project_id": "P001", + "batch_denom": "C01-P001-20200101-20210101-002", "amount": "100", "origin_tx": { "id": "0x0000000000000000000000000000000000000000000000000000000000000003", @@ -240,14 +240,14 @@ Feature: Bridge Integration And expect credit batch with properties """ { - "denom": "C01-001-20200101-20210101-002", + "denom": "C01-P001-20200101-20210101-002", "metadata": "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf", "start_date": "2020-01-01T00:00:00Z", "end_date": "2021-01-01T00:00:00Z", "open": true } """ - And expect batch supply with batch denom "C01-001-20200101-20210101-002" + And expect batch supply with batch denom "C01-P001-20200101-20210101-002" """ { "tradable_amount": "100", @@ -255,7 +255,7 @@ Feature: Bridge Integration "cancelled_amount": "0" } """ - And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-001-20200101-20210101-002" + And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-P001-20200101-20210101-002" """ { "tradable_amount": "100", @@ -294,8 +294,8 @@ Feature: Bridge Integration And expect event bridge receive with values """ { - "project_id": "C01-001", - "batch_denom": "C01-001-20200101-20210101-002", + "project_id": "P001", + "batch_denom": "C01-P001-20200101-20210101-002", "amount": "100", "origin_tx": { "id": "0x0000000000000000000000000000000000000000000000000000000000000004", @@ -306,7 +306,7 @@ Feature: Bridge Integration """ And expect total projects "1" And expect total credit batches "2" - And expect batch supply with batch denom "C01-001-20200101-20210101-002" + And expect batch supply with batch denom "C01-P001-20200101-20210101-002" """ { "tradable_amount": "200", @@ -314,7 +314,7 @@ Feature: Bridge Integration "cancelled_amount": "0" } """ - And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-001-20200101-20210101-002" + And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-P001-20200101-20210101-002" """ { "tradable_amount": "200", @@ -353,8 +353,8 @@ Feature: Bridge Integration And expect event bridge receive with values """ { - "project_id": "C01-002", - "batch_denom": "C01-002-20200101-20210101-001", + "project_id": "P002", + "batch_denom": "C01-P002-20200101-20210101-001", "amount": "100", "origin_tx": { "id": "0x0000000000000000000000000000000000000000000000000000000000000005", @@ -367,14 +367,14 @@ Feature: Bridge Integration And expect project with properties """ { - "id": "C01-002", + "id": "P002", "metadata": "regen:13toVfvC2YxrrfSXWB5h2BGHiXZURsKxWUz72uDRDSPMCrYPguGUXSC.rdf", "jurisdiction": "US-WA", "reference_id": "VCS-002" } """ And expect total credit batches "3" - And expect batch supply with batch denom "C01-002-20200101-20210101-001" + And expect batch supply with batch denom "C01-P002-20200101-20210101-001" """ { "tradable_amount": "100", @@ -382,7 +382,7 @@ Feature: Bridge Integration "cancelled_amount": "0" } """ - And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-002-20200101-20210101-001" + And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-P002-20200101-20210101-001" """ { "tradable_amount": "100", @@ -401,7 +401,7 @@ Feature: Bridge Integration "recipient": "0x1000000000000000000000000000000000000000", "credits": [ { - "batch_denom": "C01-001-20200101-20210101-001", + "batch_denom": "C01-P001-20200101-20210101-001", "amount": "200" } ] @@ -416,10 +416,10 @@ Feature: Bridge Integration "contract": "0x0000000000000000000000000000000000000001", "amount": "200", "owner": "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42", - "batch_denom": "C01-001-20200101-20210101-001" + "batch_denom": "C01-P001-20200101-20210101-001" } """ - And expect batch supply with batch denom "C01-001-20200101-20210101-001" + And expect batch supply with batch denom "C01-P001-20200101-20210101-001" """ { "tradable_amount": "0", @@ -427,7 +427,7 @@ Feature: Bridge Integration "cancelled_amount": "200" } """ - And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-001-20200101-20210101-001" + And expect batch balance with address "regen1s3x2yhc4qf59gf53hwsnhkh7gqa3eryxwj8p42" and batch denom "C01-P001-20200101-20210101-001" """ { "tradable_amount": "0", diff --git a/x/ecocredit/server/tests/features/market.feature b/x/ecocredit/server/tests/features/market.feature index 452a656383..f041f3b9d4 100644 --- a/x/ecocredit/server/tests/features/market.feature +++ b/x/ecocredit/server/tests/features/market.feature @@ -49,6 +49,7 @@ Feature: Market Integration "key": "1", "issuer": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=", "project_key": "1", + "class_key": "1", "denom": "C01-001-20200101-20210101-001", "metadata": "metadata", "start_date": "2020-01-01T00:00:00Z", diff --git a/x/ecocredit/server/testsuite/genesis.go b/x/ecocredit/server/testsuite/genesis.go index 3e39984142..1a2f42ef1b 100644 --- a/x/ecocredit/server/testsuite/genesis.go +++ b/x/ecocredit/server/testsuite/genesis.go @@ -36,12 +36,19 @@ func (s *GenesisTestSuite) TestInitExportGenesis() { require.NoError(err) projects := []baseapi.Project{ - {Id: "C01-001", Admin: sdk.AccAddress("addr1"), ClassKey: 1, Jurisdiction: "AQ", Metadata: "metadata"}, - {Id: "C01-002", Admin: sdk.AccAddress("addr2"), ClassKey: 2, Jurisdiction: "AQ", Metadata: "metadata"}, + {Id: "C01-001", Admin: sdk.AccAddress("addr1"), Jurisdiction: "AQ", Metadata: "metadata"}, + {Id: "C01-002", Admin: sdk.AccAddress("addr2"), Jurisdiction: "AQ", Metadata: "metadata"}, } projectJSON, err := json.Marshal(projects) require.NoError(err) + enrollments := []baseapi.ProjectEnrollment{ + {ProjectKey: 1, ClassKey: 1, Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED}, + {ProjectKey: 2, ClassKey: 2, Status: baseapi.ProjectEnrollmentStatus_PROJECT_ENROLLMENT_STATUS_ACCEPTED}, + } + enrollmentJSON, err := json.Marshal(enrollments) + require.NoError(err) + batches := []baseapi.Batch{ {Issuer: sdk.AccAddress("addr1"), ProjectKey: 1, Denom: "BIO01-00000000-00000000-001", Metadata: "metadata"}, {Issuer: nil, ProjectKey: 1, Denom: "BIO02-0000000-0000000-001", Metadata: "metadata"}, @@ -69,10 +76,6 @@ func (s *GenesisTestSuite) TestInitExportGenesis() { batchSeqJSON, err := json.Marshal(batchSeq) require.NoError(err) - projectSeq := []baseapi.ProjectSequence{{ClassKey: 1, NextSequence: 3}} - projectSeqJSON, err := json.Marshal(projectSeq) - require.NoError(err) - classAllowlistSettingJSON, err := json.Marshal(baseapi.ClassCreatorAllowlist{ Enabled: true, }) @@ -100,12 +103,12 @@ func (s *GenesisTestSuite) TestInitExportGenesis() { wrapper[string(proto.MessageName(&baseapi.Class{}))] = classJSON wrapper[string(proto.MessageName(&baseapi.ClassIssuer{}))] = classIssuersJSON wrapper[string(proto.MessageName(&baseapi.Project{}))] = projectJSON + wrapper[string(proto.MessageName(&baseapi.ProjectEnrollment{}))] = enrollmentJSON wrapper[string(proto.MessageName(&baseapi.Batch{}))] = batchJSON wrapper[string(proto.MessageName(&baseapi.BatchBalance{}))] = batchBalancesJSON wrapper[string(proto.MessageName(&baseapi.BatchSupply{}))] = batchSupplyJSON wrapper[string(proto.MessageName(&baseapi.ClassSequence{}))] = classSeqJSON wrapper[string(proto.MessageName(&baseapi.BatchSequence{}))] = batchSeqJSON - wrapper[string(proto.MessageName(&baseapi.ProjectSequence{}))] = projectSeqJSON wrapper[string(proto.MessageName(&baseapi.ClassCreatorAllowlist{}))] = classAllowlistSettingJSON wrapper[string(proto.MessageName(&baseapi.AllowedClassCreator{}))] = allowedClassCreatorsJSON wrapper[string(proto.MessageName(&baseapi.ClassFee{}))] = classFeeJSON diff --git a/x/ecocredit/server/testsuite/suite.go b/x/ecocredit/server/testsuite/suite.go index fbfc1560ea..21c30804b3 100644 --- a/x/ecocredit/server/testsuite/suite.go +++ b/x/ecocredit/server/testsuite/suite.go @@ -363,6 +363,7 @@ func (s *IntegrationTestSuite) createClassAndIssueBatch(admin, recipient sdk.Acc bRes, err := s.msgClient.CreateBatch(s.ctx, &basetypes.MsgCreateBatch{ Issuer: admin.String(), ProjectId: pRes.ProjectId, + ClassId: classID, Issuance: []*basetypes.BatchIssuance{{Recipient: recipient.String(), TradableAmount: tradableAmount}}, Metadata: "metadata", StartDate: &start, @@ -423,7 +424,7 @@ func (s *IntegrationTestSuite) TestScenario() { }) s.Require().NoError(err) s.Require().NotNil(createProjectRes) - s.Require().Equal("C02-001", createProjectRes.ProjectId) + s.Require().Equal("P002", createProjectRes.ProjectId) projectID := createProjectRes.ProjectId // create batch @@ -439,6 +440,7 @@ func (s *IntegrationTestSuite) TestScenario() { createBatchRes, err := s.msgClient.CreateBatch(s.ctx, &basetypes.MsgCreateBatch{ Issuer: issuer1, ProjectId: projectID, + ClassId: classID, StartDate: &time1, EndDate: &time2, Issuance: []*basetypes.BatchIssuance{ diff --git a/x/ecocredit/server/utils/utils.go b/x/ecocredit/server/utils/utils.go index fd66ee1a7c..251c9a647d 100644 --- a/x/ecocredit/server/utils/utils.go +++ b/x/ecocredit/server/utils/utils.go @@ -5,21 +5,19 @@ import ( "github.com/cosmos/cosmos-sdk/orm/types/ormerrors" "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" api "github.com/regen-network/regen-ledger/api/v2/regen/ecocredit/v1" "github.com/regen-network/regen-ledger/types/v2/math" - "github.com/regen-network/regen-ledger/x/ecocredit/v3/base" ) // GetCreditTypeFromBatchDenom extracts the classID from a batch denom string, then retrieves it from the params. -func GetCreditTypeFromBatchDenom(ctx context.Context, store api.StateStore, denom string) (*api.CreditType, error) { - classID := base.GetClassIDFromBatchDenom(denom) - classInfo, err := store.ClassTable().GetById(ctx, classID) +func GetCreditTypeFromBatchDenom(ctx context.Context, store api.StateStore, batch *api.Batch) (*api.CreditType, error) { + cls, err := store.ClassTable().Get(ctx, batch.ClassKey) if err != nil { - return nil, sdkerrors.ErrInvalidRequest.Wrapf("could not get class with ID %s: %s", classID, err.Error()) + return nil, err } - return store.CreditTypeTable().Get(ctx, classInfo.CreditTypeAbbrev) + + return store.CreditTypeTable().Get(ctx, cls.CreditTypeAbbrev) } // GetNonNegativeFixedDecs takes an arbitrary amount of decimal strings, and returns their corresponding fixed decimals diff --git a/x/ecocredit/server/utils/utils_test.go b/x/ecocredit/server/utils/utils_test.go index 4a955b480c..3867631245 100644 --- a/x/ecocredit/server/utils/utils_test.go +++ b/x/ecocredit/server/utils/utils_test.go @@ -102,18 +102,20 @@ func TestUtils_GetCreditTypeFromBatchDenom(t *testing.T) { Precision: 6, } assert.NilError(t, s.stateStore.CreditTypeTable().Insert(s.ctx, creditType)) - assert.NilError(t, s.stateStore.ClassTable().Insert(s.ctx, &api.Class{ + clsKey, err := s.stateStore.ClassTable().InsertReturningID(s.ctx, &api.Class{ Id: "C01", Admin: s.addr, Metadata: "foo", CreditTypeAbbrev: "C", - })) + }) + assert.NilError(t, err) batchDenom := "C01-000000-0000000-001" - ct, err := GetCreditTypeFromBatchDenom(s.ctx, s.stateStore, batchDenom) + batch := &api.Batch{ + Denom: batchDenom, + ClassKey: clsKey, + } + assert.NilError(t, s.stateStore.BatchTable().Insert(s.ctx, batch)) + ct, err := GetCreditTypeFromBatchDenom(s.ctx, s.stateStore, batch) assert.NilError(t, err) assert.DeepEqual(t, ct, creditType, cmpopts.IgnoreUnexported(api.CreditType{})) - - invalidDenom := "C02-0000000-0000000-001" - _, err = GetCreditTypeFromBatchDenom(s.ctx, s.stateStore, invalidDenom) - assert.ErrorContains(t, err, "could not get class with ID C02") } diff --git a/x/ecocredit/simulation/genesis.go b/x/ecocredit/simulation/genesis.go index 80a67da7f0..b1ef713f24 100644 --- a/x/ecocredit/simulation/genesis.go +++ b/x/ecocredit/simulation/genesis.go @@ -146,28 +146,6 @@ func createProject(ctx context.Context, sStore api.StateStore, project *api.Proj return 0, err } - seq, err := sStore.ProjectSequenceTable().Get(ctx, project.ClassKey) - if err != nil { - if ormerrors.IsNotFound(err) { - if err := sStore.ProjectSequenceTable().Insert(ctx, &api.ProjectSequence{ - ClassKey: project.ClassKey, - NextSequence: 2, - }); err != nil { - return 0, err - } - return pKey, nil - } - - return 0, err - } - - if err := sStore.ProjectSequenceTable().Update(ctx, &api.ProjectSequence{ - ClassKey: project.ClassKey, - NextSequence: seq.NextSequence + 1, - }); err != nil { - return 0, err - } - return pKey, nil } @@ -266,8 +244,9 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a } // create few classes + cId1 := "C01" cKey1, err := createClass(ctx, ss, &api.Class{ - Id: "C01", + Id: cId1, Admin: accs[0].Address, Metadata: metadata, CreditTypeAbbrev: "C", @@ -276,8 +255,9 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a return err } + cId2 := "C02" cKey2, err := createClass(ctx, ss, &api.Class{ - Id: "C02", + Id: cId2, Admin: accs[1].Address, Metadata: metadata, CreditTypeAbbrev: "C", @@ -312,9 +292,9 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a } // create few projects + pId1 := "P001" pKey1, err := createProject(ctx, ss, &api.Project{ - ClassKey: cKey1, - Id: "C01-001", + Id: pId1, Admin: accs[0].Address, Jurisdiction: "AQ", Metadata: metadata, @@ -323,9 +303,9 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a return err } + pId2 := "P002" pKey2, err := createProject(ctx, ss, &api.Project{ - ClassKey: cKey2, - Id: "C02-001", + Id: pId2, Admin: accs[1].Address, Jurisdiction: "AQ", Metadata: metadata, @@ -341,7 +321,7 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a if err != nil { return err } - denom, err := base.FormatBatchDenom("C01-001", batchSeq, &startDate, &endDate) + denom, err := base.FormatBatchDenom(cId1, pId2, batchSeq, &startDate, &endDate) if err != nil { return err } @@ -350,6 +330,7 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a &api.Batch{ Issuer: accs[0].Address, ProjectKey: pKey1, + ClassKey: cKey1, Denom: denom, StartDate: timestamppb.New(startDate), EndDate: timestamppb.New(endDate), @@ -365,7 +346,7 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a if err != nil { return err } - denom, err = base.FormatBatchDenom("C02-001", batchSeq, &startDate, &endDate) + denom, err = base.FormatBatchDenom(cId2, pId2, batchSeq, &startDate, &endDate) if err != nil { return err } @@ -374,6 +355,7 @@ func genGenesisState(ctx context.Context, simState *module.SimulationState, ss a &api.Batch{ Issuer: accs[2].Address, ProjectKey: pKey2, + ClassKey: cKey2, Denom: denom, StartDate: timestamppb.New(startDate.UTC()), EndDate: timestamppb.New(endDate.UTC()),