feat(x/epochs): upstream osmosis epoch module (#19697)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com>
This commit is contained in:
Hieu Vu 2024-04-04 15:10:25 +07:00 committed by GitHub
parent 0e7b7fd730
commit 1028e27f79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 10937 additions and 2 deletions

View File

@ -242,6 +242,15 @@ updates:
labels:
- "A:automerge"
- dependencies
- package-ecosystem: gomod
directory: "/x/epochs"
schedule:
interval: weekly
day: wednesday
time: "03:15"
labels:
- "A:automerge"
- dependencies
# Dependencies should be up to date on release branch
- package-ecosystem: gomod

View File

@ -62,6 +62,8 @@
- x/tx/**/*
"C:x/upgrade":
- x/upgrade/**/*
"C:x/epochs":
- x/epochs/**/*
"Type: ADR":
- docs/architecture/**/*
"Type: Build":

View File

@ -1222,3 +1222,34 @@ jobs:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
projectBaseDir: x/mint/
test-x-epochs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.22"
check-latest: true
cache: true
cache-dependency-path: x/epochs/go.sum
- uses: technote-space/get-diff-action@v6.1.2
id: git_diff
with:
PATTERNS: |
x/epochs/**/*.go
x/epochs/go.mod
x/epochs/go.sum
- name: tests
if: env.GIT_DIFF
run: |
cd x/epochs
go test -mod=readonly -timeout 30m -coverprofile=coverage.out -covermode=atomic -tags='norace ledger test_ledger_mock' ./...
- name: sonarcloud
if: ${{ env.GIT_DIFF && !github.event.pull_request.draft && env.SONAR_TOKEN != null }}
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
projectBaseDir: x/epochs/

View File

@ -0,0 +1,502 @@
// Code generated by protoc-gen-go-pulsar. DO NOT EDIT.
package modulev1
import (
_ "cosmossdk.io/api/cosmos/app/v1alpha1"
fmt "fmt"
runtime "github.com/cosmos/cosmos-proto/runtime"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoiface "google.golang.org/protobuf/runtime/protoiface"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io"
reflect "reflect"
sync "sync"
)
var (
md_Module protoreflect.MessageDescriptor
)
func init() {
file_cosmos_epochs_module_v1_module_proto_init()
md_Module = File_cosmos_epochs_module_v1_module_proto.Messages().ByName("Module")
}
var _ protoreflect.Message = (*fastReflection_Module)(nil)
type fastReflection_Module Module
func (x *Module) ProtoReflect() protoreflect.Message {
return (*fastReflection_Module)(x)
}
func (x *Module) slowProtoReflect() protoreflect.Message {
mi := &file_cosmos_epochs_module_v1_module_proto_msgTypes[0]
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_Module_messageType fastReflection_Module_messageType
var _ protoreflect.MessageType = fastReflection_Module_messageType{}
type fastReflection_Module_messageType struct{}
func (x fastReflection_Module_messageType) Zero() protoreflect.Message {
return (*fastReflection_Module)(nil)
}
func (x fastReflection_Module_messageType) New() protoreflect.Message {
return new(fastReflection_Module)
}
func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor {
return md_Module
}
// Descriptor returns message descriptor, which contains only the protobuf
// type information for the message.
func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor {
return md_Module
}
// 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_Module) Type() protoreflect.MessageType {
return _fastReflection_Module_messageType
}
// New returns a newly allocated and mutable empty message.
func (x *fastReflection_Module) New() protoreflect.Message {
return new(fastReflection_Module)
}
// Interface unwraps the message reflection interface and
// returns the underlying ProtoMessage interface.
func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage {
return (*Module)(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_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
}
// 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_Module) Has(fd protoreflect.FieldDescriptor) bool {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module 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_Module) Clear(fd protoreflect.FieldDescriptor) {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module 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_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value {
switch descriptor.FullName() {
default:
if descriptor.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module 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_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module 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_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module 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_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module 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_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
switch d.FullName() {
default:
panic(fmt.Errorf("%s is not a oneof field in cosmos.epochs.module.v1.Module", 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_Module) 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_Module) 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_Module) 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_Module) ProtoMethods() *protoiface.Methods {
size := func(input protoiface.SizeInput) protoiface.SizeOutput {
x := input.Message.Interface().(*Module)
if x == nil {
return protoiface.SizeOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Size: 0,
}
}
options := runtime.SizeInputToOptions(input)
_ = options
var n int
var l int
_ = 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().(*Module)
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 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().(*Module)
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: Module: wiretype end group for non-group")
}
if fieldNum <= 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
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,
}
}
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.0
// protoc (unknown)
// source: cosmos/epochs/module/v1/module.proto
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Module is the config object of the authz module.
type Module struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Module) Reset() {
*x = Module{}
if protoimpl.UnsafeEnabled {
mi := &file_cosmos_epochs_module_v1_module_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Module) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Module) ProtoMessage() {}
// Deprecated: Use Module.ProtoReflect.Descriptor instead.
func (*Module) Descriptor() ([]byte, []int) {
return file_cosmos_epochs_module_v1_module_proto_rawDescGZIP(), []int{0}
}
var File_cosmos_epochs_module_v1_module_proto protoreflect.FileDescriptor
var file_cosmos_epochs_module_v1_module_proto_rawDesc = []byte{
0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x2f,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65,
0x70, 0x6f, 0x63, 0x68, 0x73, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a,
0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0x27, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1d, 0xba, 0xc0, 0x96,
0xda, 0x01, 0x17, 0x0a, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69,
0x6f, 0x2f, 0x78, 0x2f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x42, 0xdc, 0x01, 0x0a, 0x1b, 0x63,
0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73,
0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75,
0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d,
0x6f, 0x73, 0x2f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43,
0x45, 0x4d, 0xaa, 0x02, 0x17, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63,
0x68, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x17, 0x43,
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x5c, 0x4d, 0x6f, 0x64,
0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x23, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c,
0x45, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31,
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x43,
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x3a, 0x3a, 0x4d,
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
file_cosmos_epochs_module_v1_module_proto_rawDescOnce sync.Once
file_cosmos_epochs_module_v1_module_proto_rawDescData = file_cosmos_epochs_module_v1_module_proto_rawDesc
)
func file_cosmos_epochs_module_v1_module_proto_rawDescGZIP() []byte {
file_cosmos_epochs_module_v1_module_proto_rawDescOnce.Do(func() {
file_cosmos_epochs_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_epochs_module_v1_module_proto_rawDescData)
})
return file_cosmos_epochs_module_v1_module_proto_rawDescData
}
var file_cosmos_epochs_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_cosmos_epochs_module_v1_module_proto_goTypes = []interface{}{
(*Module)(nil), // 0: cosmos.epochs.module.v1.Module
}
var file_cosmos_epochs_module_v1_module_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_cosmos_epochs_module_v1_module_proto_init() }
func file_cosmos_epochs_module_v1_module_proto_init() {
if File_cosmos_epochs_module_v1_module_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_cosmos_epochs_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Module); 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{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cosmos_epochs_module_v1_module_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_cosmos_epochs_module_v1_module_proto_goTypes,
DependencyIndexes: file_cosmos_epochs_module_v1_module_proto_depIdxs,
MessageInfos: file_cosmos_epochs_module_v1_module_proto_msgTypes,
}.Build()
File_cosmos_epochs_module_v1_module_proto = out.File
file_cosmos_epochs_module_v1_module_proto_rawDesc = nil
file_cosmos_epochs_module_v1_module_proto_goTypes = nil
file_cosmos_epochs_module_v1_module_proto_depIdxs = nil
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc (unknown)
// source: cosmos/epochs/v1beta1/query.proto
package epochsv1beta1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
Query_EpochInfos_FullMethodName = "/cosmos.epochs.v1beta1.Query/EpochInfos"
Query_CurrentEpoch_FullMethodName = "/cosmos.epochs.v1beta1.Query/CurrentEpoch"
)
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type QueryClient interface {
// EpochInfos provide running epochInfos
EpochInfos(ctx context.Context, in *QueryEpochsInfoRequest, opts ...grpc.CallOption) (*QueryEpochsInfoResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error)
}
type queryClient struct {
cc grpc.ClientConnInterface
}
func NewQueryClient(cc grpc.ClientConnInterface) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) EpochInfos(ctx context.Context, in *QueryEpochsInfoRequest, opts ...grpc.CallOption) (*QueryEpochsInfoResponse, error) {
out := new(QueryEpochsInfoResponse)
err := c.cc.Invoke(ctx, Query_EpochInfos_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryClient) CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error) {
out := new(QueryCurrentEpochResponse)
err := c.cc.Invoke(ctx, Query_CurrentEpoch_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
// All implementations must embed UnimplementedQueryServer
// for forward compatibility
type QueryServer interface {
// EpochInfos provide running epochInfos
EpochInfos(context.Context, *QueryEpochsInfoRequest) (*QueryEpochsInfoResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(context.Context, *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error)
mustEmbedUnimplementedQueryServer()
}
// UnimplementedQueryServer must be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (UnimplementedQueryServer) EpochInfos(context.Context, *QueryEpochsInfoRequest) (*QueryEpochsInfoResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EpochInfos not implemented")
}
func (UnimplementedQueryServer) CurrentEpoch(context.Context, *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CurrentEpoch not implemented")
}
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to QueryServer will
// result in compilation errors.
type UnsafeQueryServer interface {
mustEmbedUnimplementedQueryServer()
}
func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) {
s.RegisterService(&Query_ServiceDesc, srv)
}
func _Query_EpochInfos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryEpochsInfoRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).EpochInfos(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_EpochInfos_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).EpochInfos(ctx, req.(*QueryEpochsInfoRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Query_CurrentEpoch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryCurrentEpochRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).CurrentEpoch(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_CurrentEpoch_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).CurrentEpoch(ctx, req.(*QueryCurrentEpochRequest))
}
return interceptor(ctx, in, info, handler)
}
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Query_ServiceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.epochs.v1beta1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "EpochInfos",
Handler: _Query_EpochInfos_Handler,
},
{
MethodName: "CurrentEpoch",
Handler: _Query_CurrentEpoch_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/epochs/v1beta1/query.proto",
}

View File

@ -38,5 +38,6 @@ use (
./x/staking
./x/tx
./x/upgrade
./x/epochs
./x/accounts/defaults/lockup
)

View File

@ -50,6 +50,9 @@ import (
distr "cosmossdk.io/x/distribution"
distrkeeper "cosmossdk.io/x/distribution/keeper"
distrtypes "cosmossdk.io/x/distribution/types"
"cosmossdk.io/x/epochs"
epochskeeper "cosmossdk.io/x/epochs/keeper"
epochstypes "cosmossdk.io/x/epochs/types"
"cosmossdk.io/x/evidence"
evidencekeeper "cosmossdk.io/x/evidence/keeper"
evidencetypes "cosmossdk.io/x/evidence/types"
@ -167,6 +170,7 @@ type SimApp struct {
ConsensusParamsKeeper consensusparamkeeper.Keeper
CircuitKeeper circuitkeeper.Keeper
PoolKeeper poolkeeper.Keeper
EpochsKeeper epochskeeper.Keeper
// managers
ModuleManager *module.Manager
@ -259,7 +263,7 @@ func NewSimApp(
govtypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, circuittypes.StoreKey,
authzkeeper.StoreKey, nftkeeper.StoreKey, group.StoreKey, pooltypes.StoreKey,
accounts.StoreKey,
accounts.StoreKey, epochstypes.StoreKey,
)
// register streaming services
@ -409,6 +413,17 @@ func NewSimApp(
// If evidence needs to be handled for the app, set routes in router here and seal
app.EvidenceKeeper = *evidenceKeeper
app.EpochsKeeper = epochskeeper.NewKeeper(
runtime.NewEnvironment(runtime.NewKVStoreService(keys[epochstypes.StoreKey]), logger),
appCodec,
)
app.EpochsKeeper.SetHooks(
epochstypes.NewMultiEpochHooks(
// insert epoch hooks receivers here
),
)
/**** Module Options ****/
// NOTE: Any module instantiated in the module manager that is later modified
@ -433,6 +448,7 @@ func NewSimApp(
consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
circuit.NewAppModule(appCodec, app.CircuitKeeper),
protocolpool.NewAppModule(appCodec, app.PoolKeeper, app.AuthKeeper, app.BankKeeper),
epochs.NewAppModule(appCodec, app.EpochsKeeper),
)
app.ModuleManager.RegisterLegacyAminoCodec(legacyAmino)
app.ModuleManager.RegisterInterfaces(interfaceRegistry)
@ -453,6 +469,7 @@ func NewSimApp(
stakingtypes.ModuleName,
genutiltypes.ModuleName,
authz.ModuleName,
epochstypes.ModuleName,
)
app.ModuleManager.SetOrderEndBlockers(
govtypes.ModuleName,
@ -472,6 +489,7 @@ func NewSimApp(
minttypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
feegrant.ModuleName, nft.ModuleName, group.ModuleName, upgradetypes.ModuleName,
vestingtypes.ModuleName, consensusparamtypes.ModuleName, circuittypes.ModuleName, pooltypes.ModuleName,
epochstypes.ModuleName,
}
app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...)
app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)

View File

@ -14,6 +14,7 @@ import (
circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
@ -40,6 +41,8 @@ import (
circuittypes "cosmossdk.io/x/circuit/types"
_ "cosmossdk.io/x/distribution" // import for side-effects
distrtypes "cosmossdk.io/x/distribution/types"
_ "cosmossdk.io/x/epochs" // import for side-effects
epochstypes "cosmossdk.io/x/epochs/types"
_ "cosmossdk.io/x/evidence" // import for side-effects
evidencetypes "cosmossdk.io/x/evidence/types"
"cosmossdk.io/x/feegrant"
@ -116,6 +119,7 @@ var (
evidencetypes.ModuleName,
stakingtypes.ModuleName,
authz.ModuleName,
epochstypes.ModuleName,
},
EndBlockers: []string{
govtypes.ModuleName,
@ -151,6 +155,7 @@ var (
vestingtypes.ModuleName,
circuittypes.ModuleName,
pooltypes.ModuleName,
epochstypes.ModuleName,
},
// When ExportGenesis is not specified, the export genesis module order
// is equal to the init genesis order
@ -251,6 +256,10 @@ var (
Name: pooltypes.ModuleName,
Config: appconfig.WrapAny(&poolmodulev1.Module{}),
},
{
Name: epochstypes.ModuleName,
Config: appconfig.WrapAny(&epochsmodulev1.Module{}),
},
},
})
)

View File

@ -24,6 +24,7 @@ import (
bankkeeper "cosmossdk.io/x/bank/keeper"
circuitkeeper "cosmossdk.io/x/circuit/keeper"
distrkeeper "cosmossdk.io/x/distribution/keeper"
epochskeeper "cosmossdk.io/x/epochs/keeper"
evidencekeeper "cosmossdk.io/x/evidence/keeper"
feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
govkeeper "cosmossdk.io/x/gov/keeper"
@ -88,6 +89,7 @@ type SimApp struct {
ConsensusParamsKeeper consensuskeeper.Keeper
CircuitBreakerKeeper circuitkeeper.Keeper
PoolKeeper poolkeeper.Keeper
EpochsKeeper epochskeeper.Keeper
// simulation manager
sm *module.SimulationManager
@ -196,6 +198,7 @@ func NewSimApp(
&app.ConsensusParamsKeeper,
&app.CircuitBreakerKeeper,
&app.PoolKeeper,
&app.EpochsKeeper,
); err != nil {
panic(err)
}

View File

@ -23,6 +23,7 @@ import (
"cosmossdk.io/x/bank"
banktypes "cosmossdk.io/x/bank/types"
"cosmossdk.io/x/distribution"
"cosmossdk.io/x/epochs"
"cosmossdk.io/x/evidence"
feegrantmodule "cosmossdk.io/x/feegrant/module"
"cosmossdk.io/x/gov"
@ -212,6 +213,7 @@ func TestRunMigrations(t *testing.T) {
"evidence": evidence.AppModule{}.ConsensusVersion(),
"genutil": genutil.AppModule{}.ConsensusVersion(),
"protocolpool": protocolpool.AppModule{}.ConsensusVersion(),
"epochs": epochs.AppModule{}.ConsensusVersion(),
},
)
if tc.expRunErr {

View File

@ -19,6 +19,7 @@ require (
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/distribution v0.0.0-20240227221813-a248d05f70f4
cosmossdk.io/x/epochs v0.0.0-00010101000000-000000000000
cosmossdk.io/x/evidence v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/feegrant v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a
@ -246,6 +247,7 @@ replace (
cosmossdk.io/x/bank => ../x/bank
cosmossdk.io/x/circuit => ../x/circuit
cosmossdk.io/x/distribution => ../x/distribution
cosmossdk.io/x/epochs => ../x/epochs
cosmossdk.io/x/evidence => ../x/evidence
cosmossdk.io/x/feegrant => ../x/feegrant
cosmossdk.io/x/gov => ../x/gov

View File

@ -61,6 +61,7 @@ require (
cosmossdk.io/client/v2 v2.0.0-20230630094428-02b760776860 // indirect
cosmossdk.io/x/accounts/defaults/lockup v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f // indirect
cosmossdk.io/x/epochs v0.0.0-00010101000000-000000000000 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.2 // indirect
@ -242,6 +243,7 @@ replace (
cosmossdk.io/x/bank => ../x/bank
cosmossdk.io/x/circuit => ../x/circuit
cosmossdk.io/x/distribution => ../x/distribution
cosmossdk.io/x/epochs => ../x/epochs
cosmossdk.io/x/evidence => ../x/evidence
cosmossdk.io/x/feegrant => ../x/feegrant
cosmossdk.io/x/gov => ../x/gov

View File

@ -10,6 +10,7 @@ import (
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
countermodulev1 "cosmossdk.io/api/cosmos/counter/module/v1"
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
@ -64,6 +65,7 @@ func defaultConfig() *Config {
testutil.ParamsModuleName,
"vesting",
testutil.CircuitModuleName,
testutil.EpochsModuleName,
},
EndBlockersOrder: []string{
"crisis",
@ -106,6 +108,7 @@ func defaultConfig() *Config {
"vesting",
testutil.CircuitModuleName,
testutil.ProtocolPoolModuleName,
testutil.EpochsModuleName,
},
setInitGenesis: true,
}
@ -336,6 +339,15 @@ func CounterModule() ModuleOption {
}
}
func EpochsModule() ModuleOption {
return func(config *Config) {
config.ModuleConfigs[testutil.EpochsModuleName] = &appv1alpha1.ModuleConfig{
Name: testutil.EpochsModuleName,
Config: appconfig.WrapAny(&epochsmodulev1.Module{}),
}
}
}
func OmitInitGenesis() ModuleOption {
return func(config *Config) {
config.setInitGenesis = false

View File

@ -1,6 +1,8 @@
package testutil
import "math/rand"
import (
"math/rand"
)
func RandSliceElem[E any](r *rand.Rand, elems []E) (E, bool) {
if len(elems) == 0 {

View File

@ -22,4 +22,5 @@ const (
StakingModuleName = "staking"
TxModuleName = "tx"
UpgradeModuleName = "upgrade"
EpochsModuleName = "epochs"
)

49
x/epochs/CHANGELOG.md Normal file
View File

@ -0,0 +1,49 @@
<!--
Guiding Principles:
Changelogs are for humans, not machines.
There should be an entry for every single version.
The same types of changes should be grouped.
Versions and sections should be linkable.
The latest version comes first.
The release date of each version is displayed.
Mention whether you follow Semantic Versioning.
Usage:
Change log entries are to be added to the Unreleased section under the
appropriate stanza (see below). Each entry should ideally include a tag and
the Github issue reference in the following format:
* (<tag>) [#<issue-number>] Changelog message.
Types of changes (Stanzas):
"Features" for new features.
"Improvements" for changes in existing functionality.
"Deprecated" for soon-to-be removed features.
"Bug Fixes" for any bug fixes.
"API Breaking" for breaking exported APIs used by developers building on SDK.
Ref: https://keepachangelog.com/en/1.0.0/
-->
# Changelog
## [Unreleased]
### Features
* [#19697](https://github.com/cosmos/cosmos-sdk/pull/19697) Upstream from Osmosis
### API Breaking Changes
### Improvements
### CLI Breaking Changes
### State Machine Breaking
### Client Breaking Changes
### Bug Fixes

187
x/epochs/README.md Normal file
View File

@ -0,0 +1,187 @@
# Epochs
## Abstract
Often in the SDK, we would like to run certain code every-so often. The
purpose of `epochs` module is to allow other modules to set that they
would like to be signaled once every period. So another module can
specify it wants to execute code once a week, starting at UTC-time = x.
`epochs` creates a generalized epoch interface to other modules so that
they can easily be signaled upon such events.
## Contents
1. **[Concept](#concepts)**
2. **[State](#state)**
3. **[Events](#events)**
4. **[Keeper](#keepers)**
5. **[Hooks](#hooks)**
6. **[Queries](#queries)**
## Concepts
The epochs module defines on-chain timers that execute at fixed time intervals.
Other SDK modules can then register logic to be executed at the timer ticks.
We refer to the period in between two timer ticks as an "epoch".
Every timer has a unique identifier.
Every epoch will have a start time, and an end time, where `end time = start time + timer interval`.
On mainnet, we only utilize one identifier, with a time interval of `one day`.
The timer will tick at the first block whose block time is greater than the timer end time,
and set the start as the prior timer end time. (Notably, it's not set to the block time!)
This means that if the chain has been down for a while, you will get one timer tick per block,
until the timer has caught up.
## State
The Epochs module keeps a single `EpochInfo` per identifier.
This contains the current state of the timer with the corresponding identifier.
Its fields are modified at every timer tick.
EpochInfos are initialized as part of genesis initialization or upgrade logic,
and are only modified on begin blockers.
## Events
The `epochs` module emits the following events:
### BeginBlocker
| Type | Attribute Key | Attribute Value |
| ----------- | ------------- | --------------- |
| epoch_start | epoch_number | {epoch_number} |
| epoch_start | start_time | {start_time} |
### EndBlocker
| Type | Attribute Key | Attribute Value |
| --------- | ------------- | --------------- |
| epoch_end | epoch_number | {epoch_number} |
## Keepers
### Keeper functions
Epochs keeper module provides utility functions to manage epochs.
``` go
// Keeper is the interface for epochs module keeper
type Keeper interface {
// GetEpochInfo returns epoch info by identifier
GetEpochInfo(ctx sdk.Context, identifier string) types.EpochInfo
// SetEpochInfo set epoch info
SetEpochInfo(ctx sdk.Context, epoch types.EpochInfo)
// DeleteEpochInfo delete epoch info
DeleteEpochInfo(ctx sdk.Context, identifier string)
// IterateEpochInfo iterate through epochs
IterateEpochInfo(ctx sdk.Context, fn func(index int64, epochInfo types.EpochInfo) (stop bool))
// Get all epoch infos
AllEpochInfos(ctx sdk.Context) []types.EpochInfo
}
```
## Hooks
```go
// the first block whose timestamp is after the duration is counted as the end of the epoch
AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64)
// new epoch is next block of epoch end block
BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochNumber int64)
```
### How modules receive hooks
On hook receiver function of other modules, they need to filter
`epochIdentifier` and only do executions for only specific
epochIdentifier. Filtering epochIdentifier could be in `Params` of other
modules so that they can be modified by governance.
This is the standard dev UX of this:
```golang
func (k MyModuleKeeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) {
params := k.GetParams(ctx)
if epochIdentifier == params.DistrEpochIdentifier {
// my logic
}
}
```
### Panic isolation
If a given epoch hook panics, its state update is reverted, but we keep
proceeding through the remaining hooks. This allows more advanced epoch
logic to be used, without concern over state machine halting, or halting
subsequent modules.
This does mean that if there is behavior you expect from a prior epoch
hook, and that epoch hook reverted, your hook may also have an issue. So
do keep in mind "what if a prior hook didn't get executed" in the safety
checks you consider for a new epoch hook.
## Queries
The Epochs module provides the following queries to check the module's state.
```protobuf
service Query {
// EpochInfos provide running epochInfos
rpc EpochInfos(QueryEpochsInfoRequest) returns (QueryEpochsInfoResponse) {}
// CurrentEpoch provide current epoch of specified identifier
rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {}
}
```
### Epoch Infos
Query the currently running epochInfos
```sh
<appd> query epochs epoch-infos
```
::: details Example
An example output:
```sh
epochs:
- current_epoch: "183"
current_epoch_start_height: "2438409"
current_epoch_start_time: "2021-12-18T17:16:09.898160996Z"
duration: 86400s
epoch_counting_started: true
identifier: day
start_time: "2021-06-18T17:00:00Z"
- current_epoch: "26"
current_epoch_start_height: "2424854"
current_epoch_start_time: "2021-12-17T17:02:07.229632445Z"
duration: 604800s
epoch_counting_started: true
identifier: week
start_time: "2021-06-18T17:00:00Z"
```
:::
### Current Epoch
Query the current epoch by the specified identifier
```sh
<appd> query epochs current-epoch [identifier]
```
::: details Example
Query the current `day` epoch:
```sh
<appd> query epochs current-epoch day
```
Which in this example outputs:
```sh
current_epoch: "183"
```

27
x/epochs/autocli.go Normal file
View File

@ -0,0 +1,27 @@
package epochs
import (
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
epochsv1beta1 "cosmossdk.io/api/cosmos/epochs/v1beta1"
)
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
return &autocliv1.ModuleOptions{
Query: &autocliv1.ServiceCommandDescriptor{
Service: epochsv1beta1.Query_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "EpochInfos",
Use: "epoch-infos",
Short: "Query running epoch infos",
},
{
RpcMethod: "CurrentEpoch",
Use: "current-epoch",
Short: "Query current epoch by specified identifier",
},
},
},
}
}

74
x/epochs/depinject.go Normal file
View File

@ -0,0 +1,74 @@
package epochs
import (
"fmt"
"sort"
"golang.org/x/exp/maps"
modulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
"cosmossdk.io/x/epochs/keeper"
"cosmossdk.io/x/epochs/types"
"github.com/cosmos/cosmos-sdk/codec"
)
var _ depinject.OnePerModuleType = AppModule{}
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule) IsOnePerModuleType() {}
func init() {
appconfig.RegisterModule(&modulev1.Module{},
appconfig.Provide(ProvideModule),
appconfig.Invoke(InvokeSetHooks),
)
}
type ModuleInputs struct {
depinject.In
Config *modulev1.Module
Cdc codec.Codec
Environment appmodule.Environment
}
type ModuleOutputs struct {
depinject.Out
EpochKeeper keeper.Keeper
Module appmodule.AppModule
}
func ProvideModule(in ModuleInputs) ModuleOutputs {
k := keeper.NewKeeper(in.Environment, in.Cdc)
m := NewAppModule(in.Cdc, k)
return ModuleOutputs{EpochKeeper: k, Module: m}
}
func InvokeSetHooks(keeper keeper.Keeper, hooks map[string]types.EpochHooksWrapper) error {
if hooks == nil {
return nil
}
// Default ordering is lexical by module name.
// Explicit ordering can be added to the module config if required.
modNames := maps.Keys(hooks)
order := modNames
sort.Strings(order)
var multiHooks types.MultiEpochHooks
for _, modName := range order {
hook, ok := hooks[modName]
if !ok {
return fmt.Errorf("can't find epoch hooks for module %s", modName)
}
multiHooks = append(multiHooks, hook)
}
keeper.SetHooks(multiHooks)
return nil
}

183
x/epochs/go.mod Normal file
View File

@ -0,0 +1,183 @@
module cosmossdk.io/x/epochs
go 1.21
require (
cosmossdk.io/api v0.7.3
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.12.1-0.20231114100755-569e3ff6a0d7
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.3.1
cosmossdk.io/math v1.3.0 // indirect
cosmossdk.io/store v1.0.2
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft v0.38.6 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.4
github.com/cosmos/cosmos-sdk v0.51.0
github.com/cosmos/gogoproto v1.4.12
github.com/golang/protobuf v1.5.4
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/hashicorp/go-metrics v0.5.3 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/stretchr/testify v1.9.0
google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014
google.golang.org/grpc v1.62.1
gotest.tools/v3 v3.5.1 // indirect
)
require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.32.0-20230509103710-5e5b9fdd0180.1 // indirect
buf.build/gen/go/tendermint/tendermint/protocolbuffers/go v1.32.0-20231117195010-33ed361a9051.1 // indirect
cosmossdk.io/x/auth v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v0.13.1 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.2 // indirect
github.com/DataDog/datadog-go v4.8.3+incompatible // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cockroachdb/errors v1.11.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v1.1.0 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cometbft/cometbft-db v0.8.0 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.2 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v1.0.0 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/danieljoos/wincred v1.2.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
github.com/emicklei/dot v1.6.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-kit/kit v0.13.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.2.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-plugin v1.5.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
github.com/huandu/skiplist v1.2.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/improbable-eng/grpc-web v0.15.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.17.7 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/linxGnu/grocksdb v1.8.14 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/common v0.51.1 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/cors v1.8.3 // indirect
github.com/rs/zerolog v1.32.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tidwall/btree v1.7.0 // indirect
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
golang.org/x/mod v0.15.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.18.0 // indirect
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect
google.golang.org/protobuf v1.33.0
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v1.1.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
require cosmossdk.io/depinject v1.0.0-alpha.4
require (
cosmossdk.io/x/accounts v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/bank v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
github.com/google/orderedcode v0.0.1 // indirect
github.com/lib/pq v1.10.7 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
)
replace github.com/cosmos/cosmos-sdk => ../../.
// TODO remove post spinning out all modules
replace (
cosmossdk.io/api => ../../api
cosmossdk.io/core => ../../core
cosmossdk.io/depinject => ../../depinject
cosmossdk.io/x/accounts => ../accounts
cosmossdk.io/x/auth => ../auth
cosmossdk.io/x/bank => ../bank
cosmossdk.io/x/staking => ../staking
cosmossdk.io/x/tx => ../tx
)

1010
x/epochs/go.sum Normal file

File diff suppressed because it is too large Load Diff

86
x/epochs/keeper/abci.go Normal file
View File

@ -0,0 +1,86 @@
package keeper
import (
"context"
"fmt"
"time"
"cosmossdk.io/x/epochs/types"
"github.com/cosmos/cosmos-sdk/telemetry"
)
// BeginBlocker of epochs module.
func (k Keeper) BeginBlocker(ctx context.Context) error {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
logger := k.Logger()
headerInfo := k.environment.HeaderService.GetHeaderInfo(ctx)
err := k.EpochInfo.Walk(
ctx,
nil,
func(key string, epochInfo types.EpochInfo) (stop bool, err error) {
// If blocktime < initial epoch start time, return
if headerInfo.Time.Before(epochInfo.StartTime) {
return false, nil
}
// if epoch counting hasn't started, signal we need to start.
shouldInitialEpochStart := !epochInfo.EpochCountingStarted
epochEndTime := epochInfo.CurrentEpochStartTime.Add(epochInfo.Duration)
shouldEpochStart := (headerInfo.Time.After(epochEndTime)) || shouldInitialEpochStart
if !shouldEpochStart {
return false, nil
}
epochInfo.CurrentEpochStartHeight = headerInfo.Height
if shouldInitialEpochStart {
epochInfo.EpochCountingStarted = true
epochInfo.CurrentEpoch = 1
epochInfo.CurrentEpochStartTime = epochInfo.StartTime
logger.Debug(fmt.Sprintf("Starting new epoch with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
} else {
err := k.environment.EventService.EventManager(ctx).Emit(&types.EventEpochEnd{
EpochNumber: epochInfo.CurrentEpoch,
})
if err != nil {
return false, nil
}
if err := k.environment.BranchService.Execute(ctx, func(ctx context.Context) error {
return k.AfterEpochEnd(ctx, epochInfo.Identifier, epochInfo.CurrentEpoch)
}); err != nil {
// purposely ignoring the error here not to halt the chain if the hook fails
logger.Error(fmt.Sprintf("Error after epoch end with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
}
epochInfo.CurrentEpoch += 1
epochInfo.CurrentEpochStartTime = epochInfo.CurrentEpochStartTime.Add(epochInfo.Duration)
logger.Debug(fmt.Sprintf("Starting epoch with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
}
// emit new epoch start event, set epoch info, and run BeforeEpochStart hook
err = k.environment.EventService.EventManager(ctx).Emit(&types.EventEpochStart{
EpochNumber: epochInfo.CurrentEpoch,
EpochStartTime: epochInfo.CurrentEpochStartTime.Unix(),
})
if err != nil {
return false, err
}
err = k.EpochInfo.Set(ctx, epochInfo.Identifier, epochInfo)
if err != nil {
logger.Error(fmt.Sprintf("Error set epoch infor with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
return false, nil
}
if err := k.environment.BranchService.Execute(ctx, func(ctx context.Context) error {
return k.BeforeEpochStart(ctx, epochInfo.Identifier, epochInfo.CurrentEpoch)
}); err != nil {
// purposely ignoring the error here not to halt the chain if the hook fails
logger.Error(fmt.Sprintf("Error before epoch start with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
}
return false, nil
},
)
return err
}

View File

@ -0,0 +1,186 @@
package keeper_test
import (
"sort"
"testing"
"time"
"github.com/stretchr/testify/require"
"golang.org/x/exp/maps"
"cosmossdk.io/core/header"
"cosmossdk.io/x/epochs/types"
)
// This test is responsible for testing how epochs increment based off
// of their initial conditions, and subsequent block height / times.
func (suite *KeeperTestSuite) TestEpochInfoBeginBlockChanges() {
block1Time := time.Unix(1656907200, 0).UTC()
const defaultIdentifier = "hourly"
const defaultDuration = time.Hour
// eps is short for epsilon - in this case a negligible amount of time.
const eps = time.Nanosecond
tests := map[string]struct {
// if identifier, duration is not set, we make it defaultIdentifier and defaultDuration.
// EpochCountingStarted, if unspecified, is inferred by CurrentEpoch == 0
// StartTime is inferred to be block1Time if left blank.
initialEpochInfo types.EpochInfo
blockHeightTimePairs map[int]time.Time
expEpochInfo types.EpochInfo
}{
"First block running at exactly start time sets epoch tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time, CurrentEpochStartHeight: 1},
},
"First block run sets start time, subsequent blocks within timer interval do not cause timer tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(time.Second), 3: block1Time.Add(time.Minute), 4: block1Time.Add(30 * time.Minute)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time, CurrentEpochStartHeight: 1},
},
"Second block at exactly timer interval later does not tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(defaultDuration)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time, CurrentEpochStartHeight: 1},
},
"Second block at timer interval + epsilon later does tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(defaultDuration).Add(eps)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Hour), CurrentEpochStartHeight: 2},
},
"Downtime recovery (many intervals), first block causes 1 tick and sets current start time 1 interval ahead": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(24 * time.Hour)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Hour), CurrentEpochStartHeight: 2},
},
"Downtime recovery (many intervals), second block is at tick 2, w/ start time 2 intervals ahead": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(24 * time.Hour), 3: block1Time.Add(24 * time.Hour).Add(eps)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 3, CurrentEpochStartTime: block1Time.Add(2 * time.Hour), CurrentEpochStartHeight: 3},
},
"Many blocks between first and second tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(time.Second), 3: block1Time.Add(2 * time.Second), 4: block1Time.Add(time.Hour).Add(eps)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Hour), CurrentEpochStartHeight: 4},
},
"Distinct identifier and duration still works": {
initialEpochInfo: types.EpochInfo{Identifier: "hello", Duration: time.Minute, StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(time.Second), 3: block1Time.Add(time.Minute).Add(eps)},
expEpochInfo: types.EpochInfo{Identifier: "hello", Duration: time.Minute, StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Minute), CurrentEpochStartHeight: 3},
},
"StartTime in future won't get ticked on first block": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time.Add(time.Second), CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
// currentEpochStartHeight is 1 because that's when the timer was created on-chain
expEpochInfo: types.EpochInfo{StartTime: block1Time.Add(time.Second), CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}, CurrentEpochStartHeight: 1},
},
"StartTime in past will get ticked on first block": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time.Add(-time.Second), CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
expEpochInfo: types.EpochInfo{StartTime: block1Time.Add(-time.Second), CurrentEpoch: 1, CurrentEpochStartTime: block1Time.Add(-time.Second), CurrentEpochStartHeight: 1},
},
}
for name, test := range tests {
suite.Run(name, func() {
suite.SetupTest()
suite.Ctx = suite.Ctx.WithHeaderInfo(header.Info{Height: 1, Time: block1Time})
initialEpoch := initializeBlankEpochInfoFields(test.initialEpochInfo, defaultIdentifier, defaultDuration)
err := suite.EpochsKeeper.AddEpochInfo(suite.Ctx, initialEpoch)
suite.Require().NoError(err)
err = suite.EpochsKeeper.BeginBlocker(suite.Ctx)
suite.Require().NoError(err)
// get sorted heights
heights := maps.Keys(test.blockHeightTimePairs)
sort.Slice(heights, func(i, j int) bool { return heights[i] < heights[j] })
for _, h := range heights {
// for each height in order, run begin block
suite.Ctx = suite.Ctx.WithHeaderInfo(header.Info{Height: int64(h), Time: test.blockHeightTimePairs[h]})
err := suite.EpochsKeeper.BeginBlocker(suite.Ctx)
suite.Require().NoError(err)
}
expEpoch := initializeBlankEpochInfoFields(test.expEpochInfo, initialEpoch.Identifier, initialEpoch.Duration)
actEpoch, err := suite.EpochsKeeper.EpochInfo.Get(suite.Ctx, initialEpoch.Identifier)
suite.Require().NoError(err)
suite.Require().Equal(expEpoch, actEpoch)
})
}
}
// initializeBlankEpochInfoFields set identifier, duration and epochCountingStarted if blank in epoch
func initializeBlankEpochInfoFields(epoch types.EpochInfo, identifier string, duration time.Duration) types.EpochInfo {
if epoch.Identifier == "" {
epoch.Identifier = identifier
}
if epoch.Duration == time.Duration(0) {
epoch.Duration = duration
}
epoch.EpochCountingStarted = (epoch.CurrentEpoch != 0)
return epoch
}
func TestEpochStartingOneMonthAfterInitGenesis(t *testing.T) {
ctx, epochsKeeper, _ := Setup(t)
// On init genesis, default epochs information is set
// To check init genesis again, should make it fresh status
epochInfos, err := epochsKeeper.AllEpochInfos(ctx)
require.NoError(t, err)
for _, epochInfo := range epochInfos {
err := epochsKeeper.EpochInfo.Remove(ctx, epochInfo.Identifier)
require.NoError(t, err)
}
now := time.Now()
week := time.Hour * 24 * 7
month := time.Hour * 24 * 30
initialBlockHeight := int64(1)
ctx = ctx.WithHeaderInfo(header.Info{Height: initialBlockHeight, Time: now})
err = epochsKeeper.InitGenesis(ctx, types.GenesisState{
Epochs: []types.EpochInfo{
{
Identifier: "monthly",
StartTime: now.Add(month),
Duration: time.Hour * 24 * 30,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.HeaderInfo().Height,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
},
})
require.NoError(t, err)
// epoch not started yet
epochInfo, err := epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.CurrentEpoch, int64(0))
require.Equal(t, epochInfo.CurrentEpochStartHeight, initialBlockHeight)
require.Equal(t, epochInfo.CurrentEpochStartTime, time.Time{})
require.Equal(t, epochInfo.EpochCountingStarted, false)
// after 1 week
ctx = ctx.WithHeaderInfo(header.Info{Height: 2, Time: now.Add(week)})
err = epochsKeeper.BeginBlocker(ctx)
require.NoError(t, err)
// epoch not started yet
epochInfo, err = epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.CurrentEpoch, int64(0))
require.Equal(t, epochInfo.CurrentEpochStartHeight, initialBlockHeight)
require.Equal(t, epochInfo.CurrentEpochStartTime, time.Time{})
require.Equal(t, epochInfo.EpochCountingStarted, false)
// after 1 month
ctx = ctx.WithHeaderInfo(header.Info{Height: 3, Time: now.Add(month)})
err = epochsKeeper.BeginBlocker(ctx)
require.NoError(t, err)
// epoch started
epochInfo, err = epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.CurrentEpoch, int64(1))
require.Equal(t, epochInfo.CurrentEpochStartHeight, ctx.HeaderInfo().Height)
require.Equal(t, epochInfo.CurrentEpochStartTime.UTC().String(), now.Add(month).UTC().String())
require.Equal(t, epochInfo.EpochCountingStarted, true)
}

60
x/epochs/keeper/epoch.go Normal file
View File

@ -0,0 +1,60 @@
package keeper
import (
"context"
"fmt"
"cosmossdk.io/x/epochs/types"
)
// AddEpochInfo adds a new epoch info. Will return an error if the epoch fails validation,
// or re-uses an existing identifier.
// This method also sets the start time if left unset, and sets the epoch start height.
func (k Keeper) AddEpochInfo(ctx context.Context, epoch types.EpochInfo) error {
err := epoch.Validate()
if err != nil {
return err
}
// Check if identifier already exists
isExist, err := k.EpochInfo.Has(ctx, epoch.Identifier)
if err != nil {
return err
}
if isExist {
return fmt.Errorf("epoch with identifier %s already exists", epoch.Identifier)
}
// Initialize empty and default epoch values
if epoch.StartTime.IsZero() {
epoch.StartTime = k.environment.HeaderService.GetHeaderInfo(ctx).Time
}
epoch.CurrentEpochStartHeight = k.environment.HeaderService.GetHeaderInfo(ctx).Height
return k.EpochInfo.Set(ctx, epoch.Identifier, epoch)
}
// AllEpochInfos iterate through epochs to return all epochs info.
func (k Keeper) AllEpochInfos(ctx context.Context) ([]types.EpochInfo, error) {
epochs := []types.EpochInfo{}
err := k.EpochInfo.Walk(
ctx,
nil,
func(key string, value types.EpochInfo) (stop bool, err error) {
epochs = append(epochs, value)
return false, nil
},
)
return epochs, err
}
// NumBlocksSinceEpochStart returns the number of blocks since the epoch started.
// if the epoch started on block N, then calling this during block N (after BeforeEpochStart)
// would return 0.
// Calling it any point in block N+1 (assuming the epoch doesn't increment) would return 1.
func (k Keeper) NumBlocksSinceEpochStart(ctx context.Context, identifier string) (int64, error) {
epoch, err := k.EpochInfo.Get(ctx, identifier)
if err != nil {
return 0, fmt.Errorf("epoch with identifier %s not found", identifier)
}
return k.environment.HeaderService.GetHeaderInfo(ctx).Height - epoch.CurrentEpochStartHeight, nil
}

View File

@ -0,0 +1,101 @@
package keeper_test
import (
"time"
"cosmossdk.io/core/header"
"cosmossdk.io/x/epochs/types"
)
func (s *KeeperTestSuite) TestAddEpochInfo() {
defaultIdentifier := "default_add_epoch_info_id"
defaultDuration := time.Hour
startBlockHeight := int64(100)
startBlockTime := time.Unix(1656907200, 0).UTC()
tests := map[string]struct {
addedEpochInfo types.EpochInfo
expErr bool
expEpochInfo types.EpochInfo
}{
"simple_add": {
addedEpochInfo: types.EpochInfo{
Identifier: defaultIdentifier,
StartTime: time.Time{},
Duration: defaultDuration,
CurrentEpoch: 0,
CurrentEpochStartHeight: 0,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
expErr: false,
expEpochInfo: types.EpochInfo{
Identifier: defaultIdentifier,
StartTime: startBlockTime,
Duration: defaultDuration,
CurrentEpoch: 0,
CurrentEpochStartHeight: startBlockHeight,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
},
"zero_duration": {
addedEpochInfo: types.EpochInfo{
Identifier: defaultIdentifier,
StartTime: time.Time{},
Duration: time.Duration(0),
CurrentEpoch: 0,
CurrentEpochStartHeight: 0,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
expErr: true,
},
}
for name, test := range tests {
s.Run(name, func() {
s.SetupTest()
s.Ctx = s.Ctx.WithHeaderInfo(header.Info{Height: startBlockHeight, Time: startBlockTime})
err := s.EpochsKeeper.AddEpochInfo(s.Ctx, test.addedEpochInfo)
if !test.expErr {
s.Require().NoError(err)
actualEpochInfo, err := s.EpochsKeeper.EpochInfo.Get(s.Ctx, test.addedEpochInfo.Identifier)
s.Require().NoError(err)
s.Require().Equal(test.expEpochInfo, actualEpochInfo)
} else {
s.Require().Error(err)
}
})
}
}
func (s *KeeperTestSuite) TestDuplicateAddEpochInfo() {
identifier := "duplicate_add_epoch_info"
epochInfo := types.NewGenesisEpochInfo(identifier, time.Hour*24*30)
err := s.EpochsKeeper.AddEpochInfo(s.Ctx, epochInfo)
s.Require().NoError(err)
err = s.EpochsKeeper.AddEpochInfo(s.Ctx, epochInfo)
s.Require().Error(err)
}
func (s *KeeperTestSuite) TestEpochLifeCycle() {
s.SetupTest()
epochInfo := types.NewGenesisEpochInfo("monthly", time.Hour*24*30)
err := s.EpochsKeeper.AddEpochInfo(s.Ctx, epochInfo)
s.Require().NoError(err)
epochInfoSaved, err := s.EpochsKeeper.EpochInfo.Get(s.Ctx, "monthly")
s.Require().NoError(err)
// setup expected epoch info
expectedEpochInfo := epochInfo
expectedEpochInfo.StartTime = s.Ctx.BlockTime()
expectedEpochInfo.CurrentEpochStartHeight = s.Ctx.BlockHeight()
s.Require().Equal(expectedEpochInfo, epochInfoSaved)
allEpochs, err := s.EpochsKeeper.AllEpochInfos(s.Ctx)
s.Require().NoError(err)
s.Require().Len(allEpochs, 4)
s.Require().Equal(allEpochs[0].Identifier, "day") // alphabetical order
s.Require().Equal(allEpochs[1].Identifier, "hour")
s.Require().Equal(allEpochs[2].Identifier, "monthly")
s.Require().Equal(allEpochs[3].Identifier, "week")
}

View File

@ -0,0 +1,29 @@
package keeper
import (
"context"
"cosmossdk.io/x/epochs/types"
)
// InitGenesis sets epoch info from genesis
func (k Keeper) InitGenesis(ctx context.Context, genState types.GenesisState) error {
for _, epoch := range genState.Epochs {
err := k.AddEpochInfo(ctx, epoch)
if err != nil {
return err
}
}
return nil
}
// ExportGenesis returns the capability module's exported genesis.
func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) {
genesis := types.DefaultGenesis()
epochs, err := k.AllEpochInfos(ctx)
if err != nil {
return nil, err
}
genesis.Epochs = epochs
return genesis, nil
}

View File

@ -0,0 +1,96 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"cosmossdk.io/core/header"
"cosmossdk.io/x/epochs/types"
)
func TestEpochsExportGenesis(t *testing.T) {
ctx, epochsKeeper, _ := Setup(t)
chainStartTime := ctx.HeaderInfo().Time
chainStartHeight := ctx.HeaderInfo().Height
genesis, err := epochsKeeper.ExportGenesis(ctx)
require.NoError(t, err)
require.Len(t, genesis.Epochs, 3)
expectedEpochs := types.DefaultGenesis().Epochs
for i := 0; i < len(expectedEpochs); i++ {
expectedEpochs[i].CurrentEpochStartHeight = chainStartHeight
expectedEpochs[i].StartTime = chainStartTime
}
require.Equal(t, expectedEpochs, genesis.Epochs)
}
func TestEpochsInitGenesis(t *testing.T) {
ctx, epochsKeeper, _ := Setup(t)
// On init genesis, default epochs information is set
// To check init genesis again, should make it fresh status
epochInfos, err := epochsKeeper.AllEpochInfos(ctx)
require.NoError(t, err)
for _, epochInfo := range epochInfos {
err := epochsKeeper.EpochInfo.Remove(ctx, epochInfo.Identifier)
require.NoError(t, err)
}
// now := time.Now()
ctx.WithHeaderInfo(header.Info{Height: 1, Time: time.Now().UTC()})
// test genesisState validation
genesisState := types.GenesisState{
Epochs: []types.EpochInfo{
{
Identifier: "monthly",
StartTime: time.Time{},
Duration: time.Hour * 24,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.BlockHeight(),
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: true,
},
{
Identifier: "monthly",
StartTime: time.Time{},
Duration: time.Hour * 24,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.BlockHeight(),
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: true,
},
},
}
require.EqualError(t, genesisState.Validate(), "epoch identifier should be unique")
genesisState = types.GenesisState{
Epochs: []types.EpochInfo{
{
Identifier: "monthly",
StartTime: time.Time{},
Duration: time.Hour * 24,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.BlockHeight(),
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: true,
},
},
}
err = epochsKeeper.InitGenesis(ctx, genesisState)
require.NoError(t, err)
epochInfo, err := epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.Identifier, "monthly")
require.Equal(t, epochInfo.StartTime.UTC().String(), ctx.HeaderInfo().Time.UTC().String())
require.Equal(t, epochInfo.Duration, time.Hour*24)
require.Equal(t, epochInfo.CurrentEpoch, int64(0))
require.Equal(t, epochInfo.CurrentEpochStartHeight, ctx.BlockHeight())
require.Equal(t, epochInfo.CurrentEpochStartTime.UTC().String(), time.Time{}.String())
require.Equal(t, epochInfo.EpochCountingStarted, true)
}

View File

@ -0,0 +1,51 @@
package keeper
import (
"context"
"errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"cosmossdk.io/x/epochs/types"
)
var _ types.QueryServer = Querier{}
// Querier defines a wrapper around the x/epochs keeper providing gRPC method
// handlers.
type Querier struct {
Keeper
}
// NewQuerier initializes new querier.
func NewQuerier(k Keeper) Querier {
return Querier{Keeper: k}
}
// EpochInfos provide running epochInfos.
func (q Querier) EpochInfos(ctx context.Context, _ *types.QueryEpochsInfoRequest) (*types.QueryEpochsInfoResponse, error) {
epochs, err := q.Keeper.AllEpochInfos(ctx)
return &types.QueryEpochsInfoResponse{
Epochs: epochs,
}, err
}
// CurrentEpoch provides current epoch of specified identifier.
func (q Querier) CurrentEpoch(ctx context.Context, req *types.QueryCurrentEpochRequest) (*types.QueryCurrentEpochResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.Identifier == "" {
return nil, status.Error(codes.InvalidArgument, "identifier is empty")
}
info, err := q.Keeper.EpochInfo.Get(ctx, req.Identifier)
if err != nil {
return nil, errors.New("not available identifier")
}
return &types.QueryCurrentEpochResponse{
CurrentEpoch: info.CurrentEpoch,
}, nil
}

View File

@ -0,0 +1,22 @@
package keeper_test
import (
"cosmossdk.io/x/epochs/types"
)
func (s *KeeperTestSuite) TestQueryEpochInfos() {
s.SetupTest()
queryClient := s.queryClient
// Check that querying epoch infos on default genesis returns the default genesis epoch infos
epochInfosResponse, err := queryClient.EpochInfos(s.Ctx, &types.QueryEpochsInfoRequest{})
s.Require().NoError(err)
s.Require().Len(epochInfosResponse.Epochs, 3)
expectedEpochs := types.DefaultGenesis().Epochs
for id := range expectedEpochs {
expectedEpochs[id].StartTime = s.Ctx.BlockTime()
expectedEpochs[id].CurrentEpochStartHeight = s.Ctx.BlockHeight()
}
s.Require().Equal(expectedEpochs, epochInfosResponse.Epochs)
}

27
x/epochs/keeper/hooks.go Normal file
View File

@ -0,0 +1,27 @@
package keeper
import (
"context"
"cosmossdk.io/x/epochs/types"
)
// Hooks gets the hooks for governance Keeper
func (k Keeper) Hooks() types.EpochHooks {
if k.hooks == nil {
// return a no-op implementation if no hooks are set
return types.MultiEpochHooks{}
}
return k.hooks
}
// AfterEpochEnd gets called at the end of the epoch, end of epoch is the timestamp of first block produced after epoch duration.
func (k Keeper) AfterEpochEnd(ctx context.Context, identifier string, epochNumber int64) error {
return k.Hooks().AfterEpochEnd(ctx, identifier, epochNumber)
}
// BeforeEpochStart new epoch is next block of epoch end block
func (k Keeper) BeforeEpochStart(ctx context.Context, identifier string, epochNumber int64) error {
return k.Hooks().BeforeEpochStart(ctx, identifier, epochNumber)
}

53
x/epochs/keeper/keeper.go Normal file
View File

@ -0,0 +1,53 @@
package keeper
import (
"cosmossdk.io/collections"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/log"
"cosmossdk.io/x/epochs/types"
"github.com/cosmos/cosmos-sdk/codec"
)
type (
Keeper struct {
cdc codec.BinaryCodec
environment appmodule.Environment
hooks types.EpochHooks
Schema collections.Schema
EpochInfo collections.Map[string, types.EpochInfo]
}
)
// NewKeeper returns a new keeper by codec and storeKey inputs.
func NewKeeper(env appmodule.Environment, cdc codec.BinaryCodec) Keeper {
sb := collections.NewSchemaBuilder(env.KVStoreService)
k := Keeper{
cdc: cdc,
environment: env,
EpochInfo: collections.NewMap(sb, types.KeyPrefixEpoch, "epoch_info", collections.StringKey, codec.CollValue[types.EpochInfo](cdc)),
}
schema, err := sb.Build()
if err != nil {
panic(err)
}
k.Schema = schema
return k
}
// Set the gamm hooks.
func (k Keeper) SetHooks(eh types.EpochHooks) Keeper {
if k.hooks != nil {
panic("cannot set epochs hooks twice")
}
k.hooks = eh
return k
}
func (k Keeper) Logger() log.Logger {
return k.environment.Logger
}

View File

@ -0,0 +1,95 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/header"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
epochskeeper "cosmossdk.io/x/epochs/keeper"
"cosmossdk.io/x/epochs/types"
"github.com/cosmos/cosmos-sdk/baseapp"
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
)
type KeeperTestSuite struct {
suite.Suite
Ctx sdk.Context
environment appmodule.Environment
EpochsKeeper epochskeeper.Keeper
queryClient types.QueryClient
}
func (s *KeeperTestSuite) SetupTest() {
ctx, epochsKeeper, environment := Setup(s.T())
s.Ctx = ctx
s.EpochsKeeper = epochsKeeper
s.environment = environment
queryRouter := baseapp.NewGRPCQueryRouter()
cfg := module.NewConfigurator(nil, nil, queryRouter)
types.RegisterQueryServer(cfg.QueryServer(), epochskeeper.NewQuerier(s.EpochsKeeper))
grpcQueryService := &baseapp.QueryServiceTestHelper{
GRPCQueryRouter: queryRouter,
Ctx: s.Ctx,
}
encCfg := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{})
grpcQueryService.SetInterfaceRegistry(encCfg.InterfaceRegistry)
s.queryClient = types.NewQueryClient(grpcQueryService)
}
func Setup(t *testing.T) (sdk.Context, epochskeeper.Keeper, appmodule.Environment) {
t.Helper()
key := storetypes.NewKVStoreKey(types.StoreKey)
storeService := runtime.NewKVStoreService(key)
environment := runtime.NewEnvironment(storeService, log.NewNopLogger())
testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
ctx := testCtx.Ctx.WithHeaderInfo(header.Info{Time: time.Now()})
encCfg := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{})
epochsKeeper := epochskeeper.NewKeeper(
environment,
encCfg.Codec,
)
epochsKeeper = epochsKeeper.SetHooks(types.NewMultiEpochHooks())
ctx.WithHeaderInfo(header.Info{Height: 1, Time: time.Now().UTC(), ChainID: "epochs"})
err := epochsKeeper.InitGenesis(ctx, *types.DefaultGenesis())
require.NoError(t, err)
SetEpochStartTime(ctx, epochsKeeper)
return ctx, epochsKeeper, environment
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
func SetEpochStartTime(ctx sdk.Context, epochsKeeper epochskeeper.Keeper) {
epochs, err := epochsKeeper.AllEpochInfos(ctx)
if err != nil {
panic(err)
}
for _, epoch := range epochs {
epoch.StartTime = ctx.BlockTime()
err := epochsKeeper.EpochInfo.Remove(ctx, epoch.Identifier)
if err != nil {
panic(err)
}
err = epochsKeeper.AddEpochInfo(ctx, epoch)
if err != nil {
panic(err)
}
}
}

137
x/epochs/module.go Normal file
View File

@ -0,0 +1,137 @@
package epochs
import (
"context"
"encoding/json"
"fmt"
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/registry"
"cosmossdk.io/x/epochs/keeper"
"cosmossdk.io/x/epochs/simulation"
"cosmossdk.io/x/epochs/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/module"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
)
var (
_ module.HasName = AppModule{}
_ module.HasAminoCodec = AppModule{}
_ module.HasGRPCGateway = AppModule{}
_ module.AppModuleSimulation = AppModule{}
_ module.HasGenesis = AppModule{}
_ appmodule.AppModule = AppModule{}
_ appmodule.HasBeginBlocker = AppModule{}
)
const ConsensusVersion = 1
// AppModule implements the AppModule interface for the epochs module.
type AppModule struct {
cdc codec.Codec
keeper keeper.Keeper
}
// NewAppModule creates a new AppModule object.
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule {
return AppModule{
cdc: cdc,
keeper: keeper,
}
}
// IsAppModule implements the appmodule.AppModule interface.
func (am AppModule) IsAppModule() {}
// Name returns the epochs module's name.
func (AppModule) Name() string {
return types.ModuleName
}
// RegisterLegacyAminoCodec registers the epochs module's types for the given codec.
func (AppModule) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
}
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the epochs module.
func (AppModule) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
panic(err)
}
}
// RegisterServices registers module services.
func (am AppModule) RegisterServices(registrar grpc.ServiceRegistrar) error {
types.RegisterQueryServer(registrar, keeper.NewQuerier(am.keeper))
return nil
}
// DefaultGenesis returns the epochs module's default genesis state.
func (am AppModule) DefaultGenesis() json.RawMessage {
return am.cdc.MustMarshalJSON(types.DefaultGenesis())
}
// RegisterInterfaces implements InterfaceModule.RegisterInterfaces
func (AppModule) RegisterInterfaces(registrar registry.InterfaceRegistrar) {
}
// ValidateGenesis performs genesis state validation for the epochs module.
func (am AppModule) ValidateGenesis(bz json.RawMessage) error {
var gs types.GenesisState
if err := am.cdc.UnmarshalJSON(bz, &gs); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}
return gs.Validate()
}
// InitGenesis performs the epochs module's genesis initialization
func (am AppModule) InitGenesis(ctx context.Context, bz json.RawMessage) error {
var gs types.GenesisState
err := am.cdc.UnmarshalJSON(bz, &gs)
if err != nil {
return (fmt.Errorf("failed to unmarshal %s genesis state: %s", types.ModuleName, err))
}
return am.keeper.InitGenesis(ctx, gs)
}
// ExportGenesis returns the epochs module's exported genesis state as raw JSON bytes.
func (am AppModule) ExportGenesis(ctx context.Context) (json.RawMessage, error) {
gs, err := am.keeper.ExportGenesis(ctx)
if err != nil {
return nil, err
}
return am.cdc.MarshalJSON(gs)
}
// ConsensusVersion implements HasConsensusVersion
func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }
// BeginBlock executes all ABCI BeginBlock logic respective to the epochs module.
func (am AppModule) BeginBlock(ctx context.Context) error {
return am.keeper.BeginBlocker(ctx)
}
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the epochs module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RegisterStoreDecoder registers a decoder for epochs module's types
func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
sdr[types.StoreKey] = simtypes.NewStoreDecoderFuncFromCollectionsSchema(am.keeper.Schema)
}
// WeightedOperations returns the all the gov module operations with their respective weights.
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
return nil
}

View File

@ -0,0 +1,8 @@
version: v1
plugins:
- name: gocosmos
out: ..
opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/gogoproto/types/any
- name: grpc-gateway
out: ..
opt: logtostderr=true,allow_colon_final_segments=true

View File

@ -0,0 +1,18 @@
version: v1
managed:
enabled: true
go_package_prefix:
default: cosmossdk.io/api
except:
- buf.build/googleapis/googleapis
- buf.build/cosmos/gogo-proto
- buf.build/cosmos/cosmos-proto
override:
buf.build/cosmos/cosmos-sdk: cosmossdk.io/api
plugins:
- name: go-pulsar
out: ..
opt: paths=source_relative
- name: go-grpc
out: ..
opt: paths=source_relative

28
x/epochs/proto/buf.lock Normal file
View File

@ -0,0 +1,28 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: cosmos
repository: cosmos-proto
commit: 1935555c206d4afb9e94615dfd0fad31
digest: shake256:c74d91a3ac7ae07d579e90eee33abf9b29664047ac8816500cf22c081fec0d72d62c89ce0bebafc1f6fec7aa5315be72606717740ca95007248425102c365377
- remote: buf.build
owner: cosmos
repository: cosmos-sdk
commit: cf13c7d232dd405180c2af616fa8a075
digest: shake256:769a38e306a98339b549bc96991c97fae8bd3ceb1a7646c7bfe9a74e406ab068372970fbc5abda1891e2f3c36527cf2d3a25f631739d36900787226e564bb612
- remote: buf.build
owner: cosmos
repository: gogo-proto
commit: 5e5b9fdd01804356895f8f79a6f1ddc1
digest: shake256:0b85da49e2e5f9ebc4806eae058e2f56096ff3b1c59d1fb7c190413dd15f45dd456f0b69ced9059341c80795d2b6c943de15b120a9e0308b499e43e4b5fc2952
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 28151c0d0a1641bf938a7672c500e01d
digest: shake256:49215edf8ef57f7863004539deff8834cfb2195113f0b890dd1f67815d9353e28e668019165b9d872395871eeafcbab3ccfdb2b5f11734d3cca95be9e8d139de
- remote: buf.build
owner: protocolbuffers
repository: wellknowntypes
commit: 657250e6a39648cbb169d079a60bd9ba
digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb

18
x/epochs/proto/buf.yaml Normal file
View File

@ -0,0 +1,18 @@
version: v1
name: buf.build/mods/epochs
deps:
- buf.build/cosmos/cosmos-sdk # pin the Cosmos SDK version
- buf.build/cosmos/cosmos-proto
- buf.build/cosmos/gogo-proto
- buf.build/googleapis/googleapis
lint:
use:
- DEFAULT
- COMMENTS
- FILE_LOWER_SNAKE_CASE
except:
- UNARY_RPC
- COMMENT_FIELD
- SERVICE_SUFFIX
- PACKAGE_VERSION_SUFFIX
- RPC_REQUEST_STANDARD_NAME

View File

@ -0,0 +1,12 @@
syntax = "proto3";
package cosmos.epochs.module.v1;
import "cosmos/app/v1alpha1/module.proto";
// Module is the config object of the authz module.
message Module {
option (cosmos.app.v1alpha1.module) = {
go_import: "cosmossdk.io/x/epochs"
};
}

View File

@ -0,0 +1,21 @@
// Since: x/epochs 0.1.0
syntax = "proto3";
package cosmos.epochs.v1beta1;
import "cosmos_proto/cosmos.proto";
import "cosmos/epochs/v1beta1/genesis.proto";
option go_package = "cosmossdk.io/x/epochs/types";
// EventEpochEnd is an event emitted when an epoch end.
message EventEpochEnd {
int64 epoch_number = 1;
}
// EventEpochStart is an event emitted when an epoch start.
message EventEpochStart {
int64 epoch_number = 1;
int64 epoch_start_time = 2;
}

View File

@ -0,0 +1,60 @@
syntax = "proto3";
package cosmos.epochs.v1beta1;
import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
option go_package = "cosmossdk.io/x/epochs/types";
// EpochInfo is a struct that describes the data going into
// a timer defined by the x/epochs module.
message EpochInfo {
// identifier is a unique reference to this particular timer.
string identifier = 1;
// start_time is the time at which the timer first ever ticks.
// If start_time is in the future, the epoch will not begin until the start
// time.
google.protobuf.Timestamp start_time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// duration is the time in between epoch ticks.
// In order for intended behavior to be met, duration should
// be greater than the chains expected block time.
// Duration must be non-zero.
google.protobuf.Duration duration = 3
[(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.jsontag) = "duration,omitempty"];
// current_epoch is the current epoch number, or in other words,
// how many times has the timer 'ticked'.
// The first tick (current_epoch=1) is defined as
// the first block whose blocktime is greater than the EpochInfo start_time.
int64 current_epoch = 4;
// current_epoch_start_time describes the start time of the current timer
// interval. The interval is (current_epoch_start_time,
// current_epoch_start_time + duration] When the timer ticks, this is set to
// current_epoch_start_time = last_epoch_start_time + duration only one timer
// tick for a given identifier can occur per block.
//
// NOTE! The current_epoch_start_time may diverge significantly from the
// wall-clock time the epoch began at. Wall-clock time of epoch start may be
// >> current_epoch_start_time. Suppose current_epoch_start_time = 10,
// duration = 5. Suppose the chain goes offline at t=14, and comes back online
// at t=30, and produces blocks at every successive time. (t=31, 32, etc.)
// * The t=30 block will start the epoch for (10, 15]
// * The t=31 block will start the epoch for (15, 20]
// * The t=32 block will start the epoch for (20, 25]
// * The t=33 block will start the epoch for (25, 30]
// * The t=34 block will start the epoch for (30, 35]
// * The **t=36** block will start the epoch for (35, 40]
google.protobuf.Timestamp current_epoch_start_time = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// epoch_counting_started is a boolean, that indicates whether this
// epoch timer has began yet.
bool epoch_counting_started = 6;
reserved 7;
// current_epoch_start_height is the block height at which the current epoch
// started. (The block height at which the timer last ticked)
int64 current_epoch_start_height = 8;
}
// GenesisState defines the epochs module's genesis state.
message GenesisState {
repeated EpochInfo epochs = 1 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,33 @@
syntax = "proto3";
package cosmos.epochs.v1beta1;
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/epochs/v1beta1/genesis.proto";
option go_package = "cosmossdk.io/x/epochs/types";
// Query defines the gRPC querier service.
service Query {
// EpochInfos provide running epochInfos
rpc EpochInfos(QueryEpochsInfoRequest) returns (QueryEpochsInfoResponse) {
option (google.api.http).get = "/cosmos/epochs/v1beta1/epochs";
}
// CurrentEpoch provide current epoch of specified identifier
rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {
option (google.api.http).get = "/cosmos/epochs/v1beta1/current_epoch";
}
}
message QueryEpochsInfoRequest {}
message QueryEpochsInfoResponse {
repeated EpochInfo epochs = 1 [(gogoproto.nullable) = false];
}
message QueryCurrentEpochRequest {
string identifier = 1;
}
message QueryCurrentEpochResponse {
int64 current_epoch = 1;
}

View File

@ -0,0 +1,46 @@
package simulation
import (
"encoding/json"
"fmt"
"math/rand"
"strconv"
"time"
"cosmossdk.io/x/epochs/types"
"github.com/cosmos/cosmos-sdk/types/module"
)
// GenCommunityTax randomized CommunityTax
func GenDuration(r *rand.Rand) time.Duration {
return time.Hour * time.Duration(r.Intn(168)) // limit 1 week
}
func RandomizedEpochs(r *rand.Rand) []types.EpochInfo {
// Gen max 10 epoch
n := r.Intn(11)
var epochs []types.EpochInfo
for i := 0; i < n; i++ {
identifier := "identifier-" + strconv.Itoa(i)
duration := GenDuration(r)
epoch := types.NewGenesisEpochInfo(identifier, duration)
epochs = append(epochs, epoch)
}
return epochs
}
// RandomizedGenState generates a random GenesisState for distribution
func RandomizedGenState(simState *module.SimulationState) {
epochs := RandomizedEpochs(simState.Rand)
epochsGenesis := types.GenesisState{
Epochs: epochs,
}
bz, err := json.MarshalIndent(&epochsGenesis, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("Selected randomly generated epochs parameters:\n%s\n", bz)
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&epochsGenesis)
}

View File

@ -0,0 +1,14 @@
sonar.projectKey=cosmos-sdk-epochs
sonar.organization=cosmos
sonar.projectName=Cosmos SDK - Epochs
sonar.project.monorepo.enabled=true
sonar.sources=.
sonar.exclusions=**/*_test.go
sonar.tests=.
sonar.test.inclusions=**/*_test.go
sonar.go.coverage.reportPaths=coverage.out
sonar.sourceEncoding=UTF-8
sonar.scm.provider=git

497
x/epochs/types/events.pb.go Normal file
View File

@ -0,0 +1,497 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/events.proto
package types
import (
fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
proto "github.com/cosmos/gogoproto/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// EventEpochEnd is an event emitted when an epoch end.
type EventEpochEnd struct {
EpochNumber int64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"`
}
func (m *EventEpochEnd) Reset() { *m = EventEpochEnd{} }
func (m *EventEpochEnd) String() string { return proto.CompactTextString(m) }
func (*EventEpochEnd) ProtoMessage() {}
func (*EventEpochEnd) Descriptor() ([]byte, []int) {
return fileDescriptor_691f9b4b0a500cb4, []int{0}
}
func (m *EventEpochEnd) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EventEpochEnd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EventEpochEnd.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 *EventEpochEnd) XXX_Merge(src proto.Message) {
xxx_messageInfo_EventEpochEnd.Merge(m, src)
}
func (m *EventEpochEnd) XXX_Size() int {
return m.Size()
}
func (m *EventEpochEnd) XXX_DiscardUnknown() {
xxx_messageInfo_EventEpochEnd.DiscardUnknown(m)
}
var xxx_messageInfo_EventEpochEnd proto.InternalMessageInfo
func (m *EventEpochEnd) GetEpochNumber() int64 {
if m != nil {
return m.EpochNumber
}
return 0
}
// EventEpochStart is an event emitted when an epoch start.
type EventEpochStart struct {
EpochNumber int64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"`
EpochStartTime int64 `protobuf:"varint,2,opt,name=epoch_start_time,json=epochStartTime,proto3" json:"epoch_start_time,omitempty"`
}
func (m *EventEpochStart) Reset() { *m = EventEpochStart{} }
func (m *EventEpochStart) String() string { return proto.CompactTextString(m) }
func (*EventEpochStart) ProtoMessage() {}
func (*EventEpochStart) Descriptor() ([]byte, []int) {
return fileDescriptor_691f9b4b0a500cb4, []int{1}
}
func (m *EventEpochStart) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EventEpochStart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EventEpochStart.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 *EventEpochStart) XXX_Merge(src proto.Message) {
xxx_messageInfo_EventEpochStart.Merge(m, src)
}
func (m *EventEpochStart) XXX_Size() int {
return m.Size()
}
func (m *EventEpochStart) XXX_DiscardUnknown() {
xxx_messageInfo_EventEpochStart.DiscardUnknown(m)
}
var xxx_messageInfo_EventEpochStart proto.InternalMessageInfo
func (m *EventEpochStart) GetEpochNumber() int64 {
if m != nil {
return m.EpochNumber
}
return 0
}
func (m *EventEpochStart) GetEpochStartTime() int64 {
if m != nil {
return m.EpochStartTime
}
return 0
}
func init() {
proto.RegisterType((*EventEpochEnd)(nil), "cosmos.epochs.v1beta1.EventEpochEnd")
proto.RegisterType((*EventEpochStart)(nil), "cosmos.epochs.v1beta1.EventEpochStart")
}
func init() {
proto.RegisterFile("cosmos/epochs/v1beta1/events.proto", fileDescriptor_691f9b4b0a500cb4)
}
var fileDescriptor_691f9b4b0a500cb4 = []byte{
// 225 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4a, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x2d, 0xc8, 0x4f, 0xce, 0x28, 0xd6, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49,
0x34, 0xd4, 0x4f, 0x2d, 0x4b, 0xcd, 0x2b, 0x29, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12,
0x85, 0xa8, 0xd1, 0x83, 0xa8, 0xd1, 0x83, 0xaa, 0x91, 0x92, 0x84, 0x08, 0xc7, 0x83, 0x15, 0xe9,
0x43, 0xd5, 0x80, 0x39, 0x52, 0xca, 0xd8, 0x4d, 0x4d, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x84, 0x2a,
0x52, 0x32, 0xe2, 0xe2, 0x75, 0x05, 0x59, 0xe3, 0x0a, 0x52, 0xe4, 0x9a, 0x97, 0x22, 0xa4, 0xc8,
0xc5, 0x03, 0xd6, 0x10, 0x9f, 0x57, 0x9a, 0x9b, 0x94, 0x5a, 0x24, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1,
0x1c, 0xc4, 0x0d, 0x16, 0xf3, 0x03, 0x0b, 0x29, 0xc5, 0x71, 0xf1, 0x23, 0xf4, 0x04, 0x97, 0x24,
0x16, 0x95, 0x10, 0xa1, 0x4b, 0x48, 0x83, 0x4b, 0x00, 0xa2, 0xa4, 0x18, 0xa4, 0x23, 0xbe, 0x24,
0x33, 0x37, 0x55, 0x82, 0x09, 0xac, 0x8c, 0x2f, 0x15, 0x6e, 0x50, 0x48, 0x66, 0x6e, 0xaa, 0x93,
0xe9, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1,
0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x49, 0x43, 0xbc, 0x54, 0x9c,
0x92, 0xad, 0x97, 0x99, 0xaf, 0x5f, 0x01, 0xf3, 0x5a, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b,
0xd8, 0x47, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x88, 0x5e, 0xe4, 0x4e, 0x01, 0x00,
0x00,
}
func (m *EventEpochEnd) 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 *EventEpochEnd) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EventEpochEnd) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.EpochNumber != 0 {
i = encodeVarintEvents(dAtA, i, uint64(m.EpochNumber))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *EventEpochStart) 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 *EventEpochStart) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EventEpochStart) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.EpochStartTime != 0 {
i = encodeVarintEvents(dAtA, i, uint64(m.EpochStartTime))
i--
dAtA[i] = 0x10
}
if m.EpochNumber != 0 {
i = encodeVarintEvents(dAtA, i, uint64(m.EpochNumber))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintEvents(dAtA []byte, offset int, v uint64) int {
offset -= sovEvents(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *EventEpochEnd) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.EpochNumber != 0 {
n += 1 + sovEvents(uint64(m.EpochNumber))
}
return n
}
func (m *EventEpochStart) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.EpochNumber != 0 {
n += 1 + sovEvents(uint64(m.EpochNumber))
}
if m.EpochStartTime != 0 {
n += 1 + sovEvents(uint64(m.EpochStartTime))
}
return n
}
func sovEvents(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozEvents(x uint64) (n int) {
return sovEvents(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *EventEpochEnd) 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 ErrIntOverflowEvents
}
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: EventEpochEnd: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EventEpochEnd: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType)
}
m.EpochNumber = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvents
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.EpochNumber |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipEvents(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthEvents
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *EventEpochStart) 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 ErrIntOverflowEvents
}
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: EventEpochStart: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EventEpochStart: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType)
}
m.EpochNumber = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvents
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.EpochNumber |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochStartTime", wireType)
}
m.EpochStartTime = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvents
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.EpochStartTime |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipEvents(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthEvents
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipEvents(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEvents
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEvents
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEvents
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthEvents
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupEvents
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthEvents
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthEvents = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowEvents = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupEvents = fmt.Errorf("proto: unexpected end of group")
)

68
x/epochs/types/genesis.go Normal file
View File

@ -0,0 +1,68 @@
package types
import (
"errors"
"time"
)
// DefaultIndex is the default capability global index.
const DefaultIndex uint64 = 1
func NewGenesisState(epochs []EpochInfo) *GenesisState {
return &GenesisState{Epochs: epochs}
}
// DefaultGenesis returns the default Capability genesis state.
func DefaultGenesis() *GenesisState {
epochs := []EpochInfo{
NewGenesisEpochInfo("day", time.Hour*24), // alphabetical order
NewGenesisEpochInfo("hour", time.Hour),
NewGenesisEpochInfo("week", time.Hour*24*7),
}
return NewGenesisState(epochs)
}
// Validate performs basic genesis state validation returning an error upon any
// failure.
func (gs GenesisState) Validate() error {
epochIdentifiers := map[string]bool{}
for _, epoch := range gs.Epochs {
if err := epoch.Validate(); err != nil {
return err
}
if epochIdentifiers[epoch.Identifier] {
return errors.New("epoch identifier should be unique")
}
epochIdentifiers[epoch.Identifier] = true
}
return nil
}
// Validate also validates epoch info.
func (epoch EpochInfo) Validate() error {
if epoch.Identifier == "" {
return errors.New("epoch identifier should NOT be empty")
}
if epoch.Duration == 0 {
return errors.New("epoch duration should NOT be 0")
}
if epoch.CurrentEpoch < 0 {
return errors.New("epoch CurrentEpoch must be non-negative")
}
if epoch.CurrentEpochStartHeight < 0 {
return errors.New("epoch CurrentEpochStartHeight must be non-negative")
}
return nil
}
func NewGenesisEpochInfo(identifier string, duration time.Duration) EpochInfo {
return EpochInfo{
Identifier: identifier,
StartTime: time.Time{},
Duration: duration,
CurrentEpoch: 0,
CurrentEpochStartHeight: 0,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
}
}

View File

@ -0,0 +1,821 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/genesis.proto
package types
import (
fmt "fmt"
_ "github.com/cosmos/gogoproto/gogoproto"
proto "github.com/cosmos/gogoproto/proto"
github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types"
_ "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/timestamppb"
io "io"
math "math"
math_bits "math/bits"
time "time"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
var _ = time.Kitchen
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// EpochInfo is a struct that describes the data going into
// a timer defined by the x/epochs module.
type EpochInfo struct {
// identifier is a unique reference to this particular timer.
Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"`
// start_time is the time at which the timer first ever ticks.
// If start_time is in the future, the epoch will not begin until the start
// time.
StartTime time.Time `protobuf:"bytes,2,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"`
// duration is the time in between epoch ticks.
// In order for intended behavior to be met, duration should
// be greater than the chains expected block time.
// Duration must be non-zero.
Duration time.Duration `protobuf:"bytes,3,opt,name=duration,proto3,stdduration" json:"duration,omitempty"`
// current_epoch is the current epoch number, or in other words,
// how many times has the timer 'ticked'.
// The first tick (current_epoch=1) is defined as
// the first block whose blocktime is greater than the EpochInfo start_time.
CurrentEpoch int64 `protobuf:"varint,4,opt,name=current_epoch,json=currentEpoch,proto3" json:"current_epoch,omitempty"`
// current_epoch_start_time describes the start time of the current timer
// interval. The interval is (current_epoch_start_time,
// current_epoch_start_time + duration] When the timer ticks, this is set to
// current_epoch_start_time = last_epoch_start_time + duration only one timer
// tick for a given identifier can occur per block.
//
// NOTE! The current_epoch_start_time may diverge significantly from the
// wall-clock time the epoch began at. Wall-clock time of epoch start may be
// >> current_epoch_start_time. Suppose current_epoch_start_time = 10,
// duration = 5. Suppose the chain goes offline at t=14, and comes back online
// at t=30, and produces blocks at every successive time. (t=31, 32, etc.)
// * The t=30 block will start the epoch for (10, 15]
// * The t=31 block will start the epoch for (15, 20]
// * The t=32 block will start the epoch for (20, 25]
// * The t=33 block will start the epoch for (25, 30]
// * The t=34 block will start the epoch for (30, 35]
// * The **t=36** block will start the epoch for (35, 40]
CurrentEpochStartTime time.Time `protobuf:"bytes,5,opt,name=current_epoch_start_time,json=currentEpochStartTime,proto3,stdtime" json:"current_epoch_start_time"`
// epoch_counting_started is a boolean, that indicates whether this
// epoch timer has began yet.
EpochCountingStarted bool `protobuf:"varint,6,opt,name=epoch_counting_started,json=epochCountingStarted,proto3" json:"epoch_counting_started,omitempty"`
// current_epoch_start_height is the block height at which the current epoch
// started. (The block height at which the timer last ticked)
CurrentEpochStartHeight int64 `protobuf:"varint,8,opt,name=current_epoch_start_height,json=currentEpochStartHeight,proto3" json:"current_epoch_start_height,omitempty"`
}
func (m *EpochInfo) Reset() { *m = EpochInfo{} }
func (m *EpochInfo) String() string { return proto.CompactTextString(m) }
func (*EpochInfo) ProtoMessage() {}
func (*EpochInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_3a3d6d4398875177, []int{0}
}
func (m *EpochInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EpochInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EpochInfo.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 *EpochInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_EpochInfo.Merge(m, src)
}
func (m *EpochInfo) XXX_Size() int {
return m.Size()
}
func (m *EpochInfo) XXX_DiscardUnknown() {
xxx_messageInfo_EpochInfo.DiscardUnknown(m)
}
var xxx_messageInfo_EpochInfo proto.InternalMessageInfo
func (m *EpochInfo) GetIdentifier() string {
if m != nil {
return m.Identifier
}
return ""
}
func (m *EpochInfo) GetStartTime() time.Time {
if m != nil {
return m.StartTime
}
return time.Time{}
}
func (m *EpochInfo) GetDuration() time.Duration {
if m != nil {
return m.Duration
}
return 0
}
func (m *EpochInfo) GetCurrentEpoch() int64 {
if m != nil {
return m.CurrentEpoch
}
return 0
}
func (m *EpochInfo) GetCurrentEpochStartTime() time.Time {
if m != nil {
return m.CurrentEpochStartTime
}
return time.Time{}
}
func (m *EpochInfo) GetEpochCountingStarted() bool {
if m != nil {
return m.EpochCountingStarted
}
return false
}
func (m *EpochInfo) GetCurrentEpochStartHeight() int64 {
if m != nil {
return m.CurrentEpochStartHeight
}
return 0
}
// GenesisState defines the epochs module's genesis state.
type GenesisState struct {
Epochs []EpochInfo `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (*GenesisState) Descriptor() ([]byte, []int) {
return fileDescriptor_3a3d6d4398875177, []int{1}
}
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) {
xxx_messageInfo_GenesisState.Merge(m, src)
}
func (m *GenesisState) XXX_Size() int {
return m.Size()
}
func (m *GenesisState) XXX_DiscardUnknown() {
xxx_messageInfo_GenesisState.DiscardUnknown(m)
}
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
func (m *GenesisState) GetEpochs() []EpochInfo {
if m != nil {
return m.Epochs
}
return nil
}
func init() {
proto.RegisterType((*EpochInfo)(nil), "cosmos.epochs.v1beta1.EpochInfo")
proto.RegisterType((*GenesisState)(nil), "cosmos.epochs.v1beta1.GenesisState")
}
func init() {
proto.RegisterFile("cosmos/epochs/v1beta1/genesis.proto", fileDescriptor_3a3d6d4398875177)
}
var fileDescriptor_3a3d6d4398875177 = []byte{
// 436 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0x3f, 0x6f, 0xd3, 0x40,
0x18, 0xc6, 0x73, 0x24, 0x04, 0xe7, 0x5a, 0x24, 0x74, 0x6a, 0xe1, 0x30, 0xd2, 0xd9, 0x6a, 0x17,
0x0f, 0xe8, 0xac, 0x16, 0x98, 0x90, 0x18, 0x5c, 0x10, 0x7f, 0x06, 0x06, 0x07, 0x16, 0x24, 0x14,
0x39, 0xf6, 0xc5, 0x39, 0x81, 0x7d, 0x96, 0xef, 0x35, 0xa2, 0xdf, 0xa2, 0x23, 0x1f, 0x88, 0xa1,
0x63, 0x47, 0xa6, 0x82, 0x92, 0x8d, 0x4f, 0x81, 0x7c, 0x67, 0x47, 0x81, 0x76, 0x61, 0x4b, 0xee,
0x79, 0xde, 0xdf, 0x73, 0xcf, 0xf9, 0xc5, 0x87, 0xa9, 0xd2, 0x85, 0xd2, 0xa1, 0xa8, 0x54, 0xba,
0xd4, 0xe1, 0x97, 0xa3, 0xb9, 0x80, 0xe4, 0x28, 0xcc, 0x45, 0x29, 0xb4, 0xd4, 0xbc, 0xaa, 0x15,
0x28, 0xb2, 0x6f, 0x4d, 0xdc, 0x9a, 0x78, 0x67, 0x72, 0xf7, 0x72, 0x95, 0x2b, 0xe3, 0x08, 0xdb,
0x5f, 0xd6, 0xec, 0xb2, 0x5c, 0xa9, 0xfc, 0xb3, 0x08, 0xcd, 0xbf, 0x79, 0xb3, 0x08, 0xb3, 0xa6,
0x4e, 0x40, 0xaa, 0xb2, 0xd3, 0xbd, 0x7f, 0x75, 0x90, 0x85, 0xd0, 0x90, 0x14, 0x95, 0x35, 0x1c,
0x7c, 0x1f, 0xe2, 0xc9, 0x8b, 0x36, 0xe9, 0x75, 0xb9, 0x50, 0x84, 0x61, 0x2c, 0x33, 0x51, 0x82,
0x5c, 0x48, 0x51, 0x53, 0xe4, 0xa3, 0x60, 0x12, 0x6f, 0x9d, 0x90, 0x13, 0x8c, 0x35, 0x24, 0x35,
0xcc, 0x5a, 0x0c, 0xbd, 0xe1, 0xa3, 0x60, 0xe7, 0xd8, 0xe5, 0x36, 0x83, 0xf7, 0x19, 0xfc, 0x5d,
0x9f, 0x11, 0x39, 0xe7, 0x97, 0xde, 0xe0, 0xec, 0xa7, 0x87, 0xe2, 0x89, 0x99, 0x6b, 0x15, 0xf2,
0x1e, 0x3b, 0xfd, 0x2d, 0xe9, 0xd0, 0x20, 0xee, 0x5f, 0x41, 0x3c, 0xef, 0x0c, 0x11, 0x6b, 0x09,
0xbf, 0x2f, 0x3d, 0xd2, 0x8f, 0x3c, 0x54, 0x85, 0x04, 0x51, 0x54, 0x70, 0xfa, 0xad, 0xe5, 0x6e,
0x50, 0xe4, 0x10, 0xdf, 0x4e, 0x9b, 0xba, 0x16, 0x25, 0xcc, 0xcc, 0xd3, 0xd1, 0x91, 0x8f, 0x82,
0x61, 0xbc, 0xdb, 0x1d, 0x9a, 0x92, 0xe4, 0x23, 0xa6, 0x7f, 0x99, 0x66, 0x5b, 0x75, 0x6e, 0xfe,
0x47, 0x9d, 0xfd, 0x6d, 0xea, 0x74, 0x53, 0xed, 0x31, 0xbe, 0x6b, 0xb1, 0xa9, 0x6a, 0x4a, 0x90,
0x65, 0x6e, 0xf9, 0x22, 0xa3, 0x63, 0x1f, 0x05, 0x4e, 0xbc, 0x67, 0xd4, 0x93, 0x4e, 0x9c, 0x5a,
0x8d, 0x3c, 0xc5, 0xee, 0x75, 0x97, 0x5a, 0x0a, 0x99, 0x2f, 0x81, 0x3a, 0xa6, 0xc6, 0xbd, 0x2b,
0x81, 0xaf, 0x8c, 0xfc, 0x66, 0xe4, 0xdc, 0xba, 0xe3, 0x1c, 0xbc, 0xc5, 0xbb, 0x2f, 0xed, 0x16,
0x4d, 0x21, 0x01, 0x41, 0x9e, 0xe1, 0xb1, 0xdd, 0x1f, 0x8a, 0xfc, 0x61, 0xb0, 0x73, 0xec, 0xf3,
0x6b, 0xb7, 0x8a, 0x6f, 0x3e, 0x7d, 0x34, 0x6a, 0xbb, 0xc5, 0xdd, 0x54, 0xf4, 0xe4, 0x7c, 0xc5,
0xd0, 0xc5, 0x8a, 0xa1, 0x5f, 0x2b, 0x86, 0xce, 0xd6, 0x6c, 0x70, 0xb1, 0x66, 0x83, 0x1f, 0x6b,
0x36, 0xf8, 0xf0, 0xc0, 0x82, 0x74, 0xf6, 0x89, 0x4b, 0x15, 0x7e, 0xed, 0x77, 0x19, 0x4e, 0x2b,
0xa1, 0xe7, 0x63, 0xf3, 0x68, 0x8f, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x30, 0x02, 0x6b,
0xe9, 0x02, 0x00, 0x00,
}
func (m *EpochInfo) 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 *EpochInfo) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EpochInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.CurrentEpochStartHeight != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.CurrentEpochStartHeight))
i--
dAtA[i] = 0x40
}
if m.EpochCountingStarted {
i--
if m.EpochCountingStarted {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x30
}
n1, err1 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CurrentEpochStartTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CurrentEpochStartTime):])
if err1 != nil {
return 0, err1
}
i -= n1
i = encodeVarintGenesis(dAtA, i, uint64(n1))
i--
dAtA[i] = 0x2a
if m.CurrentEpoch != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.CurrentEpoch))
i--
dAtA[i] = 0x20
}
n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.Duration):])
if err2 != nil {
return 0, err2
}
i -= n2
i = encodeVarintGenesis(dAtA, i, uint64(n2))
i--
dAtA[i] = 0x1a
n3, err3 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.StartTime):])
if err3 != nil {
return 0, err3
}
i -= n3
i = encodeVarintGenesis(dAtA, i, uint64(n3))
i--
dAtA[i] = 0x12
if len(m.Identifier) > 0 {
i -= len(m.Identifier)
copy(dAtA[i:], m.Identifier)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.Identifier)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Epochs) > 0 {
for iNdEx := len(m.Epochs) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Epochs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *EpochInfo) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Identifier)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.StartTime)
n += 1 + l + sovGenesis(uint64(l))
l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.Duration)
n += 1 + l + sovGenesis(uint64(l))
if m.CurrentEpoch != 0 {
n += 1 + sovGenesis(uint64(m.CurrentEpoch))
}
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CurrentEpochStartTime)
n += 1 + l + sovGenesis(uint64(l))
if m.EpochCountingStarted {
n += 2
}
if m.CurrentEpochStartHeight != 0 {
n += 1 + sovGenesis(uint64(m.CurrentEpochStartHeight))
}
return n
}
func (m *GenesisState) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Epochs) > 0 {
for _, e := range m.Epochs {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
return n
}
func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenesis(x uint64) (n int) {
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *EpochInfo) 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 ErrIntOverflowGenesis
}
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: EpochInfo: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EpochInfo: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
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 ErrInvalidLengthGenesis
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Identifier = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.StartTime, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpoch", wireType)
}
m.CurrentEpoch = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CurrentEpoch |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpochStartTime", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.CurrentEpochStartTime, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochCountingStarted", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.EpochCountingStarted = bool(v != 0)
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpochStartHeight", wireType)
}
m.CurrentEpochStartHeight = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CurrentEpochStartHeight |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GenesisState) 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 ErrIntOverflowGenesis
}
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: GenesisState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Epochs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Epochs = append(m.Epochs, EpochInfo{})
if err := m.Epochs[len(m.Epochs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthGenesis
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGenesis
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGenesis
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
)

53
x/epochs/types/hooks.go Normal file
View File

@ -0,0 +1,53 @@
package types
import (
"context"
"errors"
)
type EpochHooks interface {
// the first block whose timestamp is after the duration is counted as the end of the epoch
AfterEpochEnd(ctx context.Context, epochIdentifier string, epochNumber int64) error
// new epoch is next block of epoch end block
BeforeEpochStart(ctx context.Context, epochIdentifier string, epochNumber int64) error
// Returns the name of the module implementing epoch hook.
GetModuleName() string
}
var _ EpochHooks = MultiEpochHooks{}
// combine multiple gamm hooks, all hook functions are run in array sequence.
type MultiEpochHooks []EpochHooks
// GetModuleName implements EpochHooks.
func (MultiEpochHooks) GetModuleName() string {
return ModuleName
}
func NewMultiEpochHooks(hooks ...EpochHooks) MultiEpochHooks {
return hooks
}
// AfterEpochEnd is called when epoch is going to be ended, epochNumber is the number of epoch that is ending.
func (h MultiEpochHooks) AfterEpochEnd(ctx context.Context, epochIdentifier string, epochNumber int64) error {
var errs error
for i := range h {
errs = errors.Join(errs, h[i].AfterEpochEnd(ctx, epochIdentifier, epochNumber))
}
return errs
}
// BeforeEpochStart is called when epoch is going to be started, epochNumber is the number of epoch that is starting.
func (h MultiEpochHooks) BeforeEpochStart(ctx context.Context, epochIdentifier string, epochNumber int64) error {
var errs error
for i := range h {
errs = errors.Join(errs, h[i].BeforeEpochStart(ctx, epochIdentifier, epochNumber))
}
return errs
}
// StakingHooksWrapper is a wrapper for modules to inject StakingHooks using depinject.
type EpochHooksWrapper struct{ EpochHooks }
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (EpochHooksWrapper) IsOnePerModuleType() {}

View File

@ -0,0 +1,116 @@
package types_test
import (
"context"
"testing"
"github.com/stretchr/testify/suite"
errors "cosmossdk.io/errors"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/epochs/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type KeeperTestSuite struct {
suite.Suite
Ctx sdk.Context
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
func (s *KeeperTestSuite) SetupTest() {
s.Ctx = testutil.DefaultContext(storetypes.NewKVStoreKey(types.StoreKey), storetypes.NewTransientStoreKey("transient_test"))
}
var dummyErr = errors.New("9", 9, "dummyError")
// dummyEpochHook is a struct satisfying the epoch hook interface,
// that maintains a counter for how many times its been successfully called,
// and a boolean for whether it should panic during its execution.
type dummyEpochHook struct {
successCounter int
shouldError bool
}
// GetModuleName implements types.EpochHooks.
func (*dummyEpochHook) GetModuleName() string {
return "dummy"
}
func (hook *dummyEpochHook) AfterEpochEnd(ctx context.Context, epochIdentifier string, epochNumber int64) error {
if hook.shouldError {
return dummyErr
}
hook.successCounter += 1
return nil
}
func (hook *dummyEpochHook) BeforeEpochStart(ctx context.Context, epochIdentifier string, epochNumber int64) error {
if hook.shouldError {
return dummyErr
}
hook.successCounter += 1
return nil
}
func (hook *dummyEpochHook) Clone() *dummyEpochHook {
newHook := dummyEpochHook{successCounter: hook.successCounter, shouldError: hook.shouldError}
return &newHook
}
var _ types.EpochHooks = &dummyEpochHook{}
func (s *KeeperTestSuite) TestHooksPanicRecovery() {
errorHook := dummyEpochHook{shouldError: true}
noErrorHook := dummyEpochHook{shouldError: false}
simpleHooks := []dummyEpochHook{errorHook, noErrorHook}
tests := []struct {
hooks []dummyEpochHook
expectedCounterValues []int
lenEvents int
expErr bool
}{
{[]dummyEpochHook{errorHook}, []int{0}, 0, true},
{simpleHooks, []int{0, 1, 0, 1}, 2, true},
}
for tcIndex, tc := range tests {
for epochActionSelector := 0; epochActionSelector < 2; epochActionSelector++ {
s.SetupTest()
hookRefs := []types.EpochHooks{}
for _, hook := range tc.hooks {
hookRefs = append(hookRefs, hook.Clone())
}
hooks := types.NewMultiEpochHooks(hookRefs...)
if epochActionSelector == 0 {
err := hooks.BeforeEpochStart(s.Ctx, "id", 0)
if tc.expErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
}
} else if epochActionSelector == 1 {
err := hooks.AfterEpochEnd(s.Ctx, "id", 0)
if tc.expErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
}
}
for i := 0; i < len(hooks); i++ {
epochHook := hookRefs[i].(*dummyEpochHook)
s.Require().Equal(tc.expectedCounterValues[i], epochHook.successCounter, "test case index %d", tcIndex)
}
}
}
}

View File

@ -0,0 +1,24 @@
package types
import (
"fmt"
)
func ValidateEpochIdentifierInterface(i interface{}) error {
v, ok := i.(string)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
if err := ValidateEpochIdentifierString(v); err != nil {
return err
}
return nil
}
func ValidateEpochIdentifierString(s string) error {
if s == "" {
return fmt.Errorf("empty distribution epoch identifier: %+v", s)
}
return nil
}

16
x/epochs/types/keys.go Normal file
View File

@ -0,0 +1,16 @@
package types
import (
"cosmossdk.io/collections"
)
const (
// ModuleName defines the module name.
ModuleName = "epochs"
// StoreKey defines the primary module store key.
StoreKey = ModuleName
)
// KeyPrefixEpoch defines prefix key for storing epochs.
var KeyPrefixEpoch = collections.NewPrefix(1)

911
x/epochs/types/query.pb.go Normal file
View File

@ -0,0 +1,911 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/query.proto
package types
import (
context "context"
fmt "fmt"
_ "github.com/cosmos/cosmos-sdk/types/query"
_ "github.com/cosmos/gogoproto/gogoproto"
grpc1 "github.com/cosmos/gogoproto/grpc"
proto "github.com/cosmos/gogoproto/proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type QueryEpochsInfoRequest struct {
}
func (m *QueryEpochsInfoRequest) Reset() { *m = QueryEpochsInfoRequest{} }
func (m *QueryEpochsInfoRequest) String() string { return proto.CompactTextString(m) }
func (*QueryEpochsInfoRequest) ProtoMessage() {}
func (*QueryEpochsInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{0}
}
func (m *QueryEpochsInfoRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryEpochsInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryEpochsInfoRequest.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 *QueryEpochsInfoRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryEpochsInfoRequest.Merge(m, src)
}
func (m *QueryEpochsInfoRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryEpochsInfoRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryEpochsInfoRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryEpochsInfoRequest proto.InternalMessageInfo
type QueryEpochsInfoResponse struct {
Epochs []EpochInfo `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs"`
}
func (m *QueryEpochsInfoResponse) Reset() { *m = QueryEpochsInfoResponse{} }
func (m *QueryEpochsInfoResponse) String() string { return proto.CompactTextString(m) }
func (*QueryEpochsInfoResponse) ProtoMessage() {}
func (*QueryEpochsInfoResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{1}
}
func (m *QueryEpochsInfoResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryEpochsInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryEpochsInfoResponse.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 *QueryEpochsInfoResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryEpochsInfoResponse.Merge(m, src)
}
func (m *QueryEpochsInfoResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryEpochsInfoResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryEpochsInfoResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryEpochsInfoResponse proto.InternalMessageInfo
func (m *QueryEpochsInfoResponse) GetEpochs() []EpochInfo {
if m != nil {
return m.Epochs
}
return nil
}
type QueryCurrentEpochRequest struct {
Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"`
}
func (m *QueryCurrentEpochRequest) Reset() { *m = QueryCurrentEpochRequest{} }
func (m *QueryCurrentEpochRequest) String() string { return proto.CompactTextString(m) }
func (*QueryCurrentEpochRequest) ProtoMessage() {}
func (*QueryCurrentEpochRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{2}
}
func (m *QueryCurrentEpochRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryCurrentEpochRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryCurrentEpochRequest.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 *QueryCurrentEpochRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryCurrentEpochRequest.Merge(m, src)
}
func (m *QueryCurrentEpochRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryCurrentEpochRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryCurrentEpochRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryCurrentEpochRequest proto.InternalMessageInfo
func (m *QueryCurrentEpochRequest) GetIdentifier() string {
if m != nil {
return m.Identifier
}
return ""
}
type QueryCurrentEpochResponse struct {
CurrentEpoch int64 `protobuf:"varint,1,opt,name=current_epoch,json=currentEpoch,proto3" json:"current_epoch,omitempty"`
}
func (m *QueryCurrentEpochResponse) Reset() { *m = QueryCurrentEpochResponse{} }
func (m *QueryCurrentEpochResponse) String() string { return proto.CompactTextString(m) }
func (*QueryCurrentEpochResponse) ProtoMessage() {}
func (*QueryCurrentEpochResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{3}
}
func (m *QueryCurrentEpochResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryCurrentEpochResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryCurrentEpochResponse.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 *QueryCurrentEpochResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryCurrentEpochResponse.Merge(m, src)
}
func (m *QueryCurrentEpochResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryCurrentEpochResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryCurrentEpochResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryCurrentEpochResponse proto.InternalMessageInfo
func (m *QueryCurrentEpochResponse) GetCurrentEpoch() int64 {
if m != nil {
return m.CurrentEpoch
}
return 0
}
func init() {
proto.RegisterType((*QueryEpochsInfoRequest)(nil), "cosmos.epochs.v1beta1.QueryEpochsInfoRequest")
proto.RegisterType((*QueryEpochsInfoResponse)(nil), "cosmos.epochs.v1beta1.QueryEpochsInfoResponse")
proto.RegisterType((*QueryCurrentEpochRequest)(nil), "cosmos.epochs.v1beta1.QueryCurrentEpochRequest")
proto.RegisterType((*QueryCurrentEpochResponse)(nil), "cosmos.epochs.v1beta1.QueryCurrentEpochResponse")
}
func init() { proto.RegisterFile("cosmos/epochs/v1beta1/query.proto", fileDescriptor_dacbc976c75f2414) }
var fileDescriptor_dacbc976c75f2414 = []byte{
// 396 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xbf, 0x4e, 0xe3, 0x30,
0x1c, 0xc7, 0xe3, 0xf6, 0xae, 0xd2, 0xf9, 0x7a, 0x8b, 0x75, 0x7f, 0x72, 0xb9, 0xbb, 0xb4, 0x97,
0x02, 0xaa, 0x10, 0xc4, 0xb4, 0x88, 0x85, 0x01, 0xa1, 0x22, 0x06, 0x46, 0xb2, 0xc1, 0x82, 0xd2,
0xd4, 0x0d, 0x16, 0x60, 0xa7, 0xb1, 0x8b, 0xe8, 0xca, 0x13, 0x20, 0x78, 0x00, 0xde, 0x84, 0xb9,
0x63, 0x25, 0x16, 0x26, 0x84, 0x5a, 0x1e, 0x04, 0xd5, 0x36, 0x55, 0x11, 0x29, 0xea, 0x96, 0xd8,
0x9f, 0xef, 0x9f, 0xdf, 0x2f, 0x81, 0xff, 0x23, 0x2e, 0xce, 0xb8, 0xc0, 0x24, 0xe1, 0xd1, 0xb1,
0xc0, 0xe7, 0xb5, 0x26, 0x91, 0x61, 0x0d, 0x77, 0xba, 0x24, 0xed, 0xf9, 0x49, 0xca, 0x25, 0x47,
0x3f, 0x34, 0xe2, 0x6b, 0xc4, 0x37, 0x88, 0xf3, 0x3d, 0xe6, 0x31, 0x57, 0x04, 0x1e, 0x3f, 0x69,
0xd8, 0xf9, 0x1b, 0x73, 0x1e, 0x9f, 0x12, 0x1c, 0x26, 0x14, 0x87, 0x8c, 0x71, 0x19, 0x4a, 0xca,
0x99, 0x30, 0xb7, 0xcb, 0x26, 0xad, 0x19, 0x0a, 0xa2, 0x33, 0x26, 0x89, 0x49, 0x18, 0x53, 0xa6,
0x60, 0xc3, 0x56, 0xb2, 0x9b, 0xc5, 0x84, 0x11, 0x41, 0x8d, 0xa1, 0x67, 0xc3, 0x9f, 0xfb, 0x63,
0x9b, 0x5d, 0x05, 0xed, 0xb1, 0x36, 0x0f, 0x48, 0xa7, 0x4b, 0x84, 0xf4, 0x0e, 0xe0, 0xaf, 0x77,
0x37, 0x22, 0xe1, 0x4c, 0x10, 0xb4, 0x05, 0x0b, 0xda, 0xd4, 0x06, 0xe5, 0x7c, 0xf5, 0x6b, 0xbd,
0xec, 0x67, 0x4e, 0xe8, 0x2b, 0xe9, 0x58, 0xd9, 0xf8, 0xd4, 0x7f, 0x2c, 0x59, 0x81, 0x51, 0x79,
0x9b, 0xd0, 0x56, 0xd6, 0x3b, 0xdd, 0x34, 0x25, 0x4c, 0x2a, 0xcc, 0xc4, 0x22, 0x17, 0x42, 0xda,
0x22, 0x4c, 0xd2, 0x36, 0x25, 0xa9, 0x0d, 0xca, 0xa0, 0xfa, 0x25, 0x98, 0x3a, 0xf1, 0xb6, 0xe1,
0xef, 0x0c, 0xad, 0x29, 0x56, 0x81, 0xdf, 0x22, 0x7d, 0x7e, 0xa4, 0xa2, 0x94, 0x3e, 0x1f, 0x14,
0xa3, 0x29, 0xb8, 0x7e, 0x97, 0x83, 0x9f, 0x95, 0x05, 0xba, 0x06, 0x10, 0x4e, 0x3a, 0x0a, 0xb4,
0x3a, 0x63, 0x8c, 0xec, 0x05, 0x39, 0xfe, 0xbc, 0xb8, 0x2e, 0xe7, 0x2d, 0x5e, 0xde, 0x3f, 0xdf,
0xe4, 0x4a, 0xe8, 0x1f, 0xce, 0xfe, 0x30, 0xfa, 0x15, 0xdd, 0x02, 0x58, 0x9c, 0x1e, 0x0e, 0xe1,
0x8f, 0x72, 0x32, 0x56, 0xe8, 0xac, 0xcd, 0x2f, 0x30, 0xd5, 0x56, 0x54, 0xb5, 0x25, 0xb4, 0x30,
0xa3, 0xda, 0x9b, 0xa5, 0x36, 0x36, 0xfa, 0x43, 0x17, 0x0c, 0x86, 0x2e, 0x78, 0x1a, 0xba, 0xe0,
0x6a, 0xe4, 0x5a, 0x83, 0x91, 0x6b, 0x3d, 0x8c, 0x5c, 0xeb, 0xf0, 0x8f, 0x96, 0x8b, 0xd6, 0x89,
0x4f, 0x39, 0xbe, 0x78, 0xb5, 0x91, 0xbd, 0x84, 0x88, 0x66, 0x41, 0xfd, 0x71, 0xeb, 0x2f, 0x01,
0x00, 0x00, 0xff, 0xff, 0x49, 0x28, 0xbd, 0xf7, 0x32, 0x03, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type QueryClient interface {
// EpochInfos provide running epochInfos
EpochInfos(ctx context.Context, in *QueryEpochsInfoRequest, opts ...grpc.CallOption) (*QueryEpochsInfoResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error)
}
type queryClient struct {
cc grpc1.ClientConn
}
func NewQueryClient(cc grpc1.ClientConn) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) EpochInfos(ctx context.Context, in *QueryEpochsInfoRequest, opts ...grpc.CallOption) (*QueryEpochsInfoResponse, error) {
out := new(QueryEpochsInfoResponse)
err := c.cc.Invoke(ctx, "/cosmos.epochs.v1beta1.Query/EpochInfos", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryClient) CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error) {
out := new(QueryCurrentEpochResponse)
err := c.cc.Invoke(ctx, "/cosmos.epochs.v1beta1.Query/CurrentEpoch", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// EpochInfos provide running epochInfos
EpochInfos(context.Context, *QueryEpochsInfoRequest) (*QueryEpochsInfoResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(context.Context, *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (*UnimplementedQueryServer) EpochInfos(ctx context.Context, req *QueryEpochsInfoRequest) (*QueryEpochsInfoResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EpochInfos not implemented")
}
func (*UnimplementedQueryServer) CurrentEpoch(ctx context.Context, req *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CurrentEpoch not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
}
func _Query_EpochInfos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryEpochsInfoRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).EpochInfos(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.epochs.v1beta1.Query/EpochInfos",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).EpochInfos(ctx, req.(*QueryEpochsInfoRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Query_CurrentEpoch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryCurrentEpochRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).CurrentEpoch(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.epochs.v1beta1.Query/CurrentEpoch",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).CurrentEpoch(ctx, req.(*QueryCurrentEpochRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.epochs.v1beta1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "EpochInfos",
Handler: _Query_EpochInfos_Handler,
},
{
MethodName: "CurrentEpoch",
Handler: _Query_CurrentEpoch_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/epochs/v1beta1/query.proto",
}
func (m *QueryEpochsInfoRequest) 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 *QueryEpochsInfoRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryEpochsInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
return len(dAtA) - i, nil
}
func (m *QueryEpochsInfoResponse) 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 *QueryEpochsInfoResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryEpochsInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Epochs) > 0 {
for iNdEx := len(m.Epochs) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Epochs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *QueryCurrentEpochRequest) 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 *QueryCurrentEpochRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryCurrentEpochRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Identifier) > 0 {
i -= len(m.Identifier)
copy(dAtA[i:], m.Identifier)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Identifier)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *QueryCurrentEpochResponse) 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 *QueryCurrentEpochResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryCurrentEpochResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.CurrentEpoch != 0 {
i = encodeVarintQuery(dAtA, i, uint64(m.CurrentEpoch))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *QueryEpochsInfoRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
return n
}
func (m *QueryEpochsInfoResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Epochs) > 0 {
for _, e := range m.Epochs {
l = e.Size()
n += 1 + l + sovQuery(uint64(l))
}
}
return n
}
func (m *QueryCurrentEpochRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Identifier)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func (m *QueryCurrentEpochResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.CurrentEpoch != 0 {
n += 1 + sovQuery(uint64(m.CurrentEpoch))
}
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozQuery(x uint64) (n int) {
return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *QueryEpochsInfoRequest) 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: QueryEpochsInfoRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryEpochsInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryEpochsInfoResponse) 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: QueryEpochsInfoResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryEpochsInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Epochs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Epochs = append(m.Epochs, EpochInfo{})
if err := m.Epochs[len(m.Epochs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
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 (m *QueryCurrentEpochRequest) 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: QueryCurrentEpochRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryCurrentEpochRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Identifier", 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.Identifier = 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 (m *QueryCurrentEpochResponse) 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: QueryCurrentEpochResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryCurrentEpochResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpoch", wireType)
}
m.CurrentEpoch = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CurrentEpoch |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthQuery
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupQuery
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthQuery
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -0,0 +1,236 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/query.proto
/*
Package types is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package types
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var _ = metadata.Join
func request_Query_EpochInfos_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryEpochsInfoRequest
var metadata runtime.ServerMetadata
msg, err := client.EpochInfos(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_EpochInfos_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryEpochsInfoRequest
var metadata runtime.ServerMetadata
msg, err := server.EpochInfos(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_Query_CurrentEpoch_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Query_CurrentEpoch_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryCurrentEpochRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_CurrentEpoch_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CurrentEpoch(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_CurrentEpoch_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryCurrentEpochRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_CurrentEpoch_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CurrentEpoch(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
mux.Handle("GET", pattern_Query_EpochInfos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_EpochInfos_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_EpochInfos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_CurrentEpoch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_CurrentEpoch_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_CurrentEpoch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterQueryHandler(ctx, mux, conn)
}
// RegisterQueryHandler registers the http handlers for service Query to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
}
// RegisterQueryHandlerClient registers the http handlers for service Query
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "QueryClient" to call the correct interceptors.
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
mux.Handle("GET", pattern_Query_EpochInfos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_EpochInfos_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_EpochInfos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_CurrentEpoch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_CurrentEpoch_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_CurrentEpoch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Query_EpochInfos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1}, []string{"cosmos", "epochs", "v1beta1"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_CurrentEpoch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "epochs", "v1beta1", "current_epoch"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Query_EpochInfos_0 = runtime.ForwardResponseMessage
forward_Query_CurrentEpoch_0 = runtime.ForwardResponseMessage
)